Java反射初探123456789
牛逼的框架都反射,不要问我为什么,因为我也不知道
可能是因为生成了class文件没法实例化,所以只能反射创建对象,但是在spring中,ioc就是反射实现的控制反转
看Spring4.x企业级开发实战 自己写的 第一个是Person类
package com.smart.reflect; /** * @program: chapter3 * @description: Entity * @author: Sunshine * @create: 2020-12-25 15:34 */ public class Person { private String name; private String nipples; private int hight; public Person() { } public Person(String name, String nipples, int hight) { this.name = name; this.nipples = nipples; this.hight = hight; } public void introduce () { System.out.println("name:"+ name+"; nipples:" + nipples +";hight:"+ hight ); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNipples() { return nipples; } public void setNipples(String nipples) { this.nipples = nipples; } public int getHight() { return hight; } public void setHight(int hight) { this.hight = hight; } }
package com.smart.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Method; /** * @program: chapter3 * @description: 测试反射 * @author: Sunshine * @create: 2020-12-25 15:39 */ public class ReflectTest { public static Person initByDefaultConst() throws Throwable { //1 类加载器获取对象 ClassLoader loader = Thread.currentThread().getContextClassLoader(); Class clazz = loader.loadClass("com.smart.reflect.Person"); //2 获取类的默认构造器对象 ,通过它实例化Person Constructor cons = clazz.getDeclaredConstructor((Class<?>[]) null); Person person = (Person) cons.newInstance(); //3 通过反射方法设置(属性) Method setName = clazz.getMethod("setName", String.class);
// 这里才是真正的射入属性 当然得有前面的铺垫,要不直接射不太行,你说呢? setName.invoke(person, "兔宝宝"); Method setNipples = clazz.getMethod("setNipples", String.class); setNipples.invoke(person, "pink"); Method setHignt = clazz.getMethod("setHight", int.class); setHignt.invoke(person, 170); return person; } public static void main(String[] args) { try { Person p = initByDefaultConst(); p.introduce(); } catch (Throwable throwable) { throwable.printStackTrace(); } } }
红色的方法对应的jdk源码 /** * Returns a {@code Constructor} object that reflects the specified * constructor of the class or interface represented by this * {@code Class} object. The {@code parameterTypes} parameter is * an array of {@code Class} objects that identify the constructor's * formal parameter types, in declared order. * * If this {@code Class} object represents an inner class * declared in a non-static context, the formal parameter types * include the explicit enclosing instance as the first parameter. * * @param parameterTypes the parameter array * @return The {@code Constructor} object for the constructor with the * specified parameter list * @throws NoSuchMethodException if a matching method is not found. * @throws SecurityException * If a security manager, <i>s</i>, is present and any of the * following conditions is met: * * <ul> * * <li> the caller's class loader is not the same as the * class loader of this class and invocation of * {@link SecurityManager#checkPermission * s.checkPermission} method with * {@code RuntimePermission("accessDeclaredMembers")} * denies access to the declared constructor * * <li> the caller's class loader is not the same as or an * ancestor of the class loader for the current class and * invocation of {@link SecurityManager#checkPackageAccess * s.checkPackageAccess()} denies access to the package * of this class * * </ul> * * @since JDK1.1 */ @CallerSensitive public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException { checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true); return getConstructor0(parameterTypes, Member.DECLARED); }
其实就是获取当前的这个Person类的默认的构造函数,了解的差不多就行了,别逮到一个类就往死点jdk 深入是深入了 出不来不是白给么?
下面这个图片就是借花献佛以下,下面也说了 newInsrtance()就是实例化对象用的
类装载器 CLassLoader
懒得打字 直接看图
类装载找类字节,虚机建类象组件
类加载装虚机中,需要通过下几步
查找导入类文件,校验准备和解析
校验类文件数据,是否准确不掺假
准备阶段很关键,要给静态配空间
解析阶段可以选,符号引用变直引
初始化阶段不拉胯,静态系列初始化
JVM
ClassLoader ExtClassLoader AppClassLoader
ClassLoader loader = Thread.currentThread().getContextClassLoader(); System.out.println("current Loader" + loader); System.out.println("baba Loader" + loader.getParent()); System.out.println("yeye Loader" + loader.getParent().getParent());
"C:\Program Files\Java\jdk1.8.0_152\bin\java.exe" "-javaagent:E:\idea\IntelliJ IDEA 2020.2.4\lib\idea_rt.jar=57015:E:\idea\IntelliJ IDEA 2020.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_152\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_152\jre\lib\rt.jar;C:\Users\Administrator\Desktop\spring4.x\wangpan\chapter3\target\classes;D:\ToolsForDev\repository\org\springframework\boot\spring-boot-starter-web\1.3.3.RELEASE\spring-boot-starter-web-1.3.3.RELEASE.jar;D:\ToolsForDev\repository\org\springframework\boot\spring-boot-starter\1.3.3.RELEASE\spring-boot-starter-1.3.3.RELEASE.jar;D:\ToolsForDev\repository\org\springframework\boot\spring-boot\1.3.3.RELEASE\spring-boot-1.3.3.RELEASE.jar;D:\ToolsForDev\repository\org\springframework\boot\spring-boot-autoconfigure\1.3.3.RELEASE\spring-boot-autoconfigure-1.3.3.RELEASE.jar;D:\ToolsForDev\repository\org\springframework\boot\spring-boot-starter-logging\1.3.3.RELEASE\spring-boot-starter-logging-1.3.3.RELEASE.jar;D:\ToolsForDev\repository\ch\qos\logback\logback-classic\1.1.5\logback-classic-1.1.5.jar;D:\ToolsForDev\repository\ch\qos\logback\logback-core\1.1.5\logback-core-1.1.5.jar;D:\ToolsForDev\repository\org\slf4j\slf4j-api\1.7.16\slf4j-api-1.7.16.jar;D:\ToolsForDev\repository\org\slf4j\jcl-over-slf4j\1.7.16\jcl-over-slf4j-1.7.16.jar;D:\ToolsForDev\repository\org\slf4j\jul-to-slf4j\1.7.16\jul-to-slf4j-1.7.16.jar;D:\ToolsForDev\repository\org\slf4j\log4j-over-slf4j\1.7.16\log4j-over-slf4j-1.7.16.jar;D:\ToolsForDev\repository\org\yaml\snakeyaml\1.16\snakeyaml-1.16.jar;D:\ToolsForDev\repository\org\springframework\boot\spring-boot-starter-tomcat\1.3.3.RELEASE\spring-boot-starter-tomcat-1.3.3.RELEASE.jar;D:\ToolsForDev\repository\org\apache\tomcat\embed\tomcat-embed-logging-juli\8.0.32\tomcat-embed-logging-juli-8.0.32.jar;D:\ToolsForDev\repository\org\apache\tomcat\embed\tomcat-embed-websocket\8.0.32\tomcat-embed-websocket-8.0.32.jar;D:\ToolsForDev\repository\org\springframework\boot\spring-boot-starter-validation\1.3.3.RELEASE\spring-boot-starter-validation-1.3.3.RELEASE.jar;D:\ToolsForDev\repository\org\hibernate\hibernate-validator\5.2.4.Final\hibernate-validator-5.2.4.Final.jar;D:\ToolsForDev\repository\javax\validation\validation-api\1.1.0.Final\validation-api-1.1.0.Final.jar;D:\ToolsForDev\repository\org\jboss\logging\jboss-logging\3.3.0.Final\jboss-logging-3.3.0.Final.jar;D:\ToolsForDev\repository\com\fasterxml\classmate\1.1.0\classmate-1.1.0.jar;D:\ToolsForDev\repository\com\fasterxml\jackson\core\jackson-databind\2.6.5\jackson-databind-2.6.5.jar;D:\ToolsForDev\repository\com\fasterxml\jackson\core\jackson-annotations\2.6.5\jackson-annotations-2.6.5.jar;D:\ToolsForDev\repository\com\fasterxml\jackson\core\jackson-core\2.6.5\jackson-core-2.6.5.jar;D:\ToolsForDev\repository\org\springframework\spring-web\4.2.5.RELEASE\spring-web-4.2.5.RELEASE.jar;D:\ToolsForDev\repository\org\springframework\spring-aop\4.2.5.RELEASE\spring-aop-4.2.5.RELEASE.jar;D:\ToolsForDev\repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;D:\ToolsForDev\repository\org\springframework\spring-beans\4.2.5.RELEASE\spring-beans-4.2.5.RELEASE.jar;D:\ToolsForDev\repository\org\springframework\spring-context\4.2.5.RELEASE\spring-context-4.2.5.RELEASE.jar;D:\ToolsForDev\repository\org\springframework\spring-webmvc\4.2.5.RELEASE\spring-webmvc-4.2.5.RELEASE.jar;D:\ToolsForDev\repository\org\springframework\spring-expression\4.2.5.RELEASE\spring-expression-4.2.5.RELEASE.jar;D:\ToolsForDev\repository\org\springframework\boot\spring-boot-starter-jdbc\1.3.3.RELEASE\spring-boot-starter-jdbc-1.3.3.RELEASE.jar;D:\ToolsForDev\repository\org\apache\tomcat\tomcat-jdbc\8.0.32\tomcat-jdbc-8.0.32.jar;D:\ToolsForDev\repository\org\apache\tomcat\tomcat-juli\8.0.32\tomcat-juli-8.0.32.jar;D:\ToolsForDev\repository\org\springframework\spring-jdbc\4.2.5.RELEASE\spring-jdbc-4.2.5.RELEASE.jar;D:\ToolsForDev\repository\org\springframework\spring-tx\4.2.5.RELEASE\spring-tx-4.2.5.RELEASE.jar;D:\ToolsForDev\repository\org\springframework\boot\spring-boot-starter-actuator\1.3.3.RELEASE\spring-boot-starter-actuator-1.3.3.RELEASE.jar;D:\ToolsForDev\repository\org\springframework\boot\spring-boot-actuator\1.3.3.RELEASE\spring-boot-actuator-1.3.3.RELEASE.jar;D:\ToolsForDev\repository\mysql\mysql-connector-java\5.1.38\mysql-connector-java-5.1.38.jar;D:\ToolsForDev\repository\org\apache\tomcat\embed\tomcat-embed-core\8.0.32\tomcat-embed-core-8.0.32.jar;D:\ToolsForDev\repository\org\apache\tomcat\embed\tomcat-embed-el\8.0.32\tomcat-embed-el-8.0.32.jar;D:\ToolsForDev\repository\javax\servlet\jstl\1.2\jstl-1.2.jar;D:\ToolsForDev\repository\org\springframework\spring-core\4.2.5.RELEASE\spring-core-4.2.5.RELEASE.jar" com.smart.reflect.ReflectTest name:兔宝宝; nipples:pink;hight:170
当前加载器 current Loadersun.misc.Launcher$AppClassLoader@18b4aac2
当前加载器的爹
baba Loadersun.misc.Launcher$ExtClassLoader@33c7353a
当前加载器的爷爷
yeye Loadernull
Process finished with exit code 0
这个费点劲 还得启动
用这个省事
package com.smart.utils; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.security.CodeSource; import java.security.ProtectionDomain; /** * tools to find which jar does the class come from * @author : chenxh * @date: 16-04-0 */ public class ClassLocationUtils { /** * find the location of the class come from * @param cls * @return */ public static String where(final Class cls) { if (cls == null)throw new IllegalArgumentException("null input: cls"); URL result = null; final String clsAsResource = cls.getName().replace('.', '/').concat(".class"); final ProtectionDomain pd = cls.getProtectionDomain(); if (pd != null) { final CodeSource cs = pd.getCodeSource(); if (cs != null) result = cs.getLocation(); if (result != null) { if ("file".equals(result.getProtocol())) { try { if (result.toExternalForm().endsWith(".jar") || result.toExternalForm().endsWith(".zip")) result = new URL("jar:".concat(result.toExternalForm()) .concat("!/").concat(clsAsResource)); else if (new File(result.getFile()).isDirectory()) result = new URL(result, clsAsResource); } catch (MalformedURLException ignore) {} } } } if (result == null) { final ClassLoader clsLoader = cls.getClassLoader(); result = clsLoader != null ? clsLoader.getResource(clsAsResource) : ClassLoader.getSystemResource(clsAsResource); } return result.toString(); } }
自己试了一下 嘿 您猜怎么着 还真好使
file:/C:/Users/Administrator/Desktop/spring4.x/wangpan/chapter3/target/classes/com/smart/reflect/Person.class
新鲜刺激的东西永远都有,玩之前掂量掂量自己几斤几两