注解与反射_2 - 小记

1.类加载器的作用?
源文件.java ------ Javac编译器 ------字节码文件.class ------- 类加载器-------字节码校验器--------解释器 --------OS
作用:将class文件字节码内容,加载到内存中,静态域转化为方法区的运行时刻的数据结构,然后再堆中生成class对象,
作为方法区数据的访问入口。

2.类缓存?
查找类,一但加载到类加载器中,将维持/缓存一段时间后,JVM会进行垃圾回收。

3.类加载器的分类?
注:util.*基础类库

1.引导类:复杂核心类库的装载C++编写 2.扩展类:负责jre/lib/ext 目录下的jar包 或 ext.dirs下的jar包装载入工作库 3.系统类:把properties中的jar包装入工作库。

4. 双亲委派机制:防止同名包、类与jdk中的相冲突!
加载类时,首先通知appLoader, 是否有缓存 , 能加载即加载;
若无,则通知其父类加载器extLoader , 同上: 是否有缓存 , 能加载即加载;
若无,则通知其父类加载器BootstrapLoader , 同上: 是否有缓存 , 能加载即加载;
若再无?则又一层一层地向子类加载器走,能加载即加载。
若到appLoader,仍然是无缓存,则加载,同时加载到缓存中!
注解与反射_2 - 小记
文章图片

这个过程是不停在找自己的父级,所以叫双亲委派机制。
看下概念!双亲委派机制描述: 某个特定的类加载器在接到加载类的请求时, 首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回; 只有父类加载器无法完成此加载任务时,才自己去加载。

问题:能不能自己写个类叫java.lang.System?回答:通常情况下不可以,由于类加载采用委托机制。 它会不断查找自己的父类加载器,是否有该同名类,不断递归;而System类是Bootstrap加载器加载的,就算自己重写, 也总是使用Java系统提供的System,自己写的System类根本没有机会得到加载。但是! 可以自己定义一个类加载器来达到这个目的,为了避免双亲委托机制,这个类加载器也必须是特殊的。 由于系统自带的三个类加载器都加载特定目录下的类, 如果我们自己的类加载器放在一个特殊的目录,那么系统的加载器就无法加载, 最终由我们自己的加载器加载。


5.反射创建类对象?
Class对象调用newInstance()方法;
满足:a.类必须有一个无参构造方法;若无,则必须要传入参数,通过invoke方法;
b.类的构造方法需要足够。Declared...

6.通过构造方法创建对象?
通过Class对象调用getDeclaredConstructer(Class ...parameterTypes)取得构造器方法;
向构造器传入对象数组,包含构造器所需的各个参数;
通过Constructer对象实例化对象。

7.调用指定的方法?
getMethod()、invoke()等方法
package com.tencent.reflection; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class Test7 { //通过反射创建对象 public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {Class c1 = Class.forName("com.tencent.reflection.User"); //1.构造对象 - 调用的无参构造器! User user = (User) c1.newInstance(); System.out.println(user); //若User未写无参构造,则报错//2.通过构造器创建对象 Constructor constructor = c1.getDeclaredConstructor(String.class , int.class); User user1 = (User) constructor.newInstance("jx" , 21); //如果参数为空,会报错.因为User现没有无参构造方法 System.out.println(user1); //3.利用反射调用普通方法 User user3 = (User)c1.newInstance(); //获得一个方法参数1:方法名参数2:参数类型 Method setName = c1.getDeclaredMethod("setName", String.class); //invoke激活的意思, (对象 , 方法传参数的值) setName.invoke(user3 , "jiaxin"); Method setAge = c1.getDeclaredMethod("setAge", int.class); setAge.invoke(user3 , 21); System.out.println("user3 = " + user3); //User{name='jiaxin', age=21}User user4 = (User) c1.newInstance(); Field name = c1.getDeclaredField("name"); name.setAccessible(true); //必须加! 开启可访问的权限!本身不可操作私有属性,所以需要关闭安全检测. name.set(user4 , "jx"); System.out.println(user4); //User{name='jx', age=0}} }

8.获得类的属性、方法、构造器?
package com.tencent.reflection; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Method; public class Test6 {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {Class c1 =Class.forName("com.tencent.reflection.User"); //获得类名字 System.out.println(c1.getName()); //com.tencent.reflection.User System.out.println(c1.getSimpleName()); //User//获得类属性 Field[] fields = c1.getFields(); for (Field field : fields) { System.out.println(field); }fields = c1.getDeclaredFields(); /* * private java.lang.String com.tencent.reflection.User.name * private int com.tencent.reflection.User.age * */ for (Field field : fields) { System.out.println(field); }//private java.lang.String com.tencent.reflection.User.name System.out.println(c1.getDeclaredField("name")); //私有成员所以用DeclaredMethod[] methods = c1.getDeclaredMethods(); /* public java.lang.String com.tencent.reflection.User.toString() public java.lang.String com.tencent.reflection.User.getName() public void com.tencent.reflection.User.setName(java.lang.String) public int com.tencent.reflection.User.getAge() public void com.tencent.reflection.User.setAge(int) * */ for (Method method : methods) { System.out.println(method); }/* * 总结:带Declared可以查出私有成员/方法 * 如果不带,只能查出public的 * *///获得指定构造器 - 根据参数匹配 Constructor dec = c1.getDeclaredConstructor(String.class , int.class); System.out.println(dec); } }


9.获取泛型信息?
public class Test9 {public static void t1(Map map , List list) { System.out.println("t1"); }public static Map t2(Map map) { System.out.println("t2"); return null; }public static void test1() throws NoSuchMethodException { Method method = Test9.class.getMethod("t1", Map.class, List.class); //获取泛型的参数类型 Type[] types = method.getGenericParameterTypes(); for (Type type : types) { /* java.util.Map java.util.List */ System.out.println(type); //判断type是不是一个结构化参数类型ParameterizedType-类型判断 if(type instanceof ParameterizedType) { Type[] t = ((ParameterizedType) type).getActualTypeArguments(); for (Type type1 : t) { System.out.println(type1); } } System.out.println(""); }System.out.println(""); }public static void test2() throws NoSuchMethodException { Method method = Test9.class.getMethod("t2", Map.class); Type typeReturn= method.getGenericReturnType(); if(typeReturn instanceof ParameterizedType) { Type[] t = ((ParameterizedType) typeReturn).getActualTypeArguments(); for (Type type : t) { System.out.println(type); } /* class java.lang.String class com.tencent.reflection.User */ } }public static void main(String[] args) throws NoSuchMethodException {} }

10.获取注解信息?
//联系反射操作注解 public class Test10 {public static void main(String[] args) throws NoSuchFieldException {/* * ORM: Object relationship Mapping 对象关系映射 * */Class c1 = User.class; //通过反射获得类的注解 Annotation[] annotations =c1.getDeclaredAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation); }System.out.println(""); //获得注解的value值 TableXin table = (TableXin) c1.getAnnotation(TableXin.class); String value = https://www.it610.com/article/table.value(); System.out.println(value); System.out.println(""); //获得注解的属性 Field field = c1.getDeclaredField("name"); System.out.println(field); FieldXin fieldXin = field.getAnnotation(FieldXin.class); System.out.println(fieldXin.columnName()); System.out.println(fieldXin.type()); System.out.println(fieldXin.length()); //空指针异常!} }


11.注:User类
package com.tencent.reflection; @TableXin("user") public class User {@FieldXin(columnName = "user_name" , type = "int" , length = 10) private String name; @FieldXin(columnName = "user_age" , type = "int" , length = 10) private int age; public User(String name, int age) { this.name = name; this.age = age; } public User(){}public String getName() { return name; }public void setName(String name) { this.name = name; }public int getAge() { return age; }public void setAge(int age) { this.age = age; }@Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } }

【注解与反射_2 - 小记】

    推荐阅读