什么是反射?
* 动态语言:程序运行时,可以改变程序结构或变量类型。典型语言:JS、Python等。
* 在学反射之前,我们需要知道,java不是动态语言,但有一定的动态特性,
* 可以利用反射机制、字节码操作获得类似动态语言的特性,这种特性让编程更灵活。
* 反射机制:指的是可以在运行的时候加载、探知、使用编译期间完全未知的类;
* 例子:Class c = class.forName("cn.oyh.annotation.Student"),这个Student
* 在编译的时候是无法辨认的,就是编译器不知道它是什么类,因为它是一段字符串,但是
* 反射机制可以在运行时加载到这个类。加载完这个类后,在堆内存中,就存在一个Class
* 类型的对象,这个对象包含了完整的类的结构信息,就是属性和方法。这个对象就像一面
* 镜子,透过这个镜子看到类的结构,所以称之为:反射。
作用:
*作用:
* 1.动态加载类、动态获取类的信息;
* 2.动态构造对象;
* 3.动态调用类和对象的任意方法、构造器;
* 4.动态调用和处理属性;
* 5,获取泛型信息;
* 6.处理注解;
获取类对象的三种方法:
/*
获取Class对象
1.getClass()
2.Class.forName(),最常用
3.运用class语法
*/
String path = "cn.oyh.annotation.Student";
Class strc2 = path.getClass();
Class c = Class.forName(path);
Class strc = String.class;
反射获取一个类的对象只有一个:
String类:
String path = "cn.oyh.annotation.Student";
Class strc2 = path.getClass();
Class c = Class.forName(path);
Class strc = String.class;
System.out.println(strc2==strc);//一样的,都是String类
System.out.println(c);
System.out.println(c.hashCode());
Class c2 = Class.forName(path);
//会发现都一样,因为同个类只会被加载一次,一类只有一个对象
System.out.println(c2.hashCode());
执行:
true
class cn.oyh.annotation.Student
356573597
356573597
数组:
int[] arr1 = new int[5];
int[] arr2 = new int[10];
int[][] arr3 = new int[10][3];
double[] arr4 = new double[10];
System.out.println(arr1.getClass().hashCode());
System.out.println(arr2.getClass().hashCode());
System.out.println(arr3.getClass().hashCode());
System.out.println(arr4.getClass().hashCode());
执行:
1735600054
1735600054
21685669
2133927002
可以发现不同维度,不同类型的就不是同一个,只是长度不同也是一个对象。
获取名、属性、方法、构造器:
//获取名
System.out.println(c.getName());//包名+类名
System.out.println(c.getSimpleName());//类名
//获取属性
Field[] fields = c.getFields();//只能获得public修饰的属性
System.out.println(fields.length);
Field f = c.getDeclaredField("snume");//指定获取
Field[] fields2= c.getDeclaredFields();//所有的属性
System.out.println(fields2.length);
for(Field temp:fields2){
System.out.println(temp);
}
//获取方法
Method[] methods = c.getDeclaredMethods();
Method method =c.getDeclaredMethod("getId",null);
Method method2 =c.getDeclaredMethod("setId",int.class);
for(Method m:methods){
System.out.println("方法"+m);
}
//获取构造器
Constructor[] constructors =c.getDeclaredConstructors();
for(Constructor con:constructors){
System.out.println("构造器"+con);
}
Constructor con = c.getDeclaredConstructor(int.class,String.class,int.class);
System.out.println(con);
执行:
cn.oyh.annotation.Student
Student
0
3
private int cn.oyh.annotation.Student.id
private java.lang.String cn.oyh.annotation.Student.snume
private int cn.oyh.annotation.Student.age
方法public int cn.oyh.annotation.Student.getId()
方法public void cn.oyh.annotation.Student.setAge(int)
方法public void cn.oyh.annotation.Student.setSnume(java.lang.String)
方法public java.lang.String cn.oyh.annotation.Student.getSnume()
方法public int cn.oyh.annotation.Student.getAge()
方法public void cn.oyh.annotation.Student.setId(int)
构造器public cn.oyh.annotation.Student()
构造器public cn.oyh.annotation.Student(int,java.lang.String,int)
public cn.oyh.annotation.Student(int,java.lang.String,int)