反射机制基础
一、反射
1、反射机制
反射机制:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以 及动态调用对象的方法的功能称为java语言的反射机制。
总之,反射是发生在程序运行期间的行为--java的一个动静态机制
注意:
创建对象的时候,拿到的都是当天前类型Class对象的一个镜像|赋值体
在类加载的时候,会在内存中存在当天前类型的一个Class对象,一个类的Class对象中存储这个类的所有信息(属性,方法,构造器...)
只要我们能够获取这个类型的Class对象,就可以对这个类做一切操作
2、获取Class对象
Class 类的实例:
表示正在运行的 Java 应用程序中的类和接口
获取源头(Class对象)三种方式:
对象.getClass()
类名.class
Class.forName("类的权限命名:包名+类名")
//1.对象.getClass() Class cls1="哈哈".getClass();
Class cls2="呵呵".getClass();
System.out.println(cls1==cls2);
//2.类名.class Class cls3=String.class;
System.out.println(cls1==cls3);
System.out.println(cls3);
//3.Class.forName("类的权限命名:包名+类名") 推荐
Class cls4=Class.forName("java.lang.String");
System.out.println(cls3==cls4);
//4.根据子类的Class对象获取父类的Class对象
Class cls5=cls4.getSuperclass();
System.out.println(cls5);
//5.获取基本数据类型的Class对象
Class base1=int.class;
System.out.println(base1);
Class cls6=Integer.class;
System.out.println(base1==cls6);
Class base2=Integer.TYPE;
//得到对应的基本数据类型的class对象 System.out.println(base1==base2);
运行结果:
true true class java.lang.String true class java.lang.Object int false true
3、Class类常用方法:
//常用的方法
//1.getName() 包名+类名
System.out.println(cls5.getName());
//2\. Class<?>[] getInterfaces()
Class[] arr=cls4.getInterfaces();
System.out.println(Arrays.toString(arr));
//3.String getSimpleName()
System.out.println(cls4.getSimpleName());
//4.boolean isInterface() isPrimitive()
System.out.println(Integer.class.isPrimitive());
System.out.println(Integer.TYPE.isPrimitive());
3、通过反射创建对象
1)通过反射获取到类中的构造器
2)根据构造器创建对象
构造器Constructor对象.newInstance(实参)方法
直接通过class类的newIntance()方法创建对象,方法没有参数 调用空构造
//先获取类的Class Class cls=Person.class;
//通过Class类的newInstance方法,调用空构造
Person p=(Person) (cls.newInstance());
//通过Class中的方法,获取类的构造器
/* *
Constructor<T> getConstructor(Class<?>... parameterTypes) 返回一个 Constructor 对象, 它反映此 Class 对象所表示的类的指定公共构造方法。 Constructor<?>[] getConstructors() 返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。
*/
Constructor<Person> cs=cls.getConstructor(int.class,String.class,int.class);
Person p2=cs.newInstance(1,"赵",2); System.out.println(p2);
/* *
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 返回一个 Constructor 对象, 该对象反映此 Class 对象所表示的类或接口的指定构造方法。 Constructor<?>[] getDeclaredConstructors() 返回 Constructor 对象的一个数组, 这些对象反映此 Class 对象表示的类声明的所有构造方法。
*/
Constructor<Person>[] cs2=cls.getDeclaredConstructors();
System.out.println(Arrays.toString(cs2));
//cs[1]为私有构造器,使用需要放开权限
cs2[1].setAccessible(true);
Person p3=cs2[1].newInstance(12,"李");
cs2[1].setAccessible(false);
System.out.println(p3);
4、操作方法 调用方法,能给方法传递实参
Method类:提供关于类或接口上单独某个方法(以及如何访问该方法)的信息。所反映的方法可能是类方法或实例方法(包括抽象方法)。
/* Method getDeclaredMethod(String name, Class<?>... parameterTypes) 返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。 Method[] getDeclaredMethods() Method getMethod(String name, Class<?>... parameterTypes) 返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。 Method[] getMethods() 返回一个包含某些 Method 对象的数组, 这些对象反映此 Class 对象所表示的类或接口 (包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。 */
Method[] md=cls.getDeclaredMethods();
System.out.println(Arrays.toString(md));
Person p=(Person) cls.newInstance();
Method me=cls.getDeclaredMethod("setAge",int.class);
me.invoke(p, 1); System.out.println(p);
5、Field类
/*反射操作类中的字段 能设置值 能获取值 Field getDeclaredField(String name) 返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。 Field[] getDeclaredFields() 返回 Field 对象的一个数组, 这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。 Field getField(String name)返回一个 Field 对象, 它反映此 Class 对象所表示的类或接口的指定公共成员字段。 Field[] getFields() */
Field f=cls.getDeclaredField("name");
//Object get(Object obj) 返回指定对象上此 Field 表示的字段的值。
//打开权限 f.setAccessible(true);
Person p=new Person(1,"黑猫警长",22);
f.set(p,"一只耳");
f.setAccessible(false);
System.out.println(p.getName());
二、总结
1、Map与Collection总结
clipboard.png2、每个类的Class对象唯一
3、TreeMap调用有参构造器,传入比较器
TreeMap<Person,Integer> tm2=new TreeMap(Comparator MyComparator);
4、获取Method之后使用invoke传入参数问题
第一个参数为类的实例,第二个参数为相应函数中的参数
静态方法执行的时候,invoke第一个参数可以为null