1:动态语言:
在运行时,能够改变程序结构和类型。(java不行,如:python,js,ruby)
c,c++,java却可以通过反射,操作字节码获得类似动态的特性。
2.反射机制:
可以在运行时,加载,探索,使用编译期间未知的类型。
在运行时,加载一个只知道类名的类,便能知道这个类的属性和方法,可以用来生成对象,对于对象可以调用其方法和属性。
(加载类,其实就是在堆内存中生成一个Class类型的对象(jvm通过加载器),并且每个类型都只会有一个Class对象。所以Class对象是反射的根源)
3.获取Class:
Class string = Class.forName("com.me.test.reflect.User");//一般用类全名(即包括包名)(之所可以不用,是import了
Class string2 = "stirng".getClass();//通过对象获取
Class string3 = String.class;//通过类型获取
a.数组是不同的维度对应不同的Class
b.像class interface enu void type private等这些关键词代表的意义也是Class类型
4.功能作用:
特别注意对于一些方法对于可变参数(即数组)而言,数组参数要转成Object,如果参数本身就是数组,不转换会该参数的元素被误认为,是多个参数的封装到数组了。
Object object = f.invoke(null, (Object) new String[] { "a", "b" },(Object) new String[] { "aa", "ab" });
获取属性,方法 ,构造器的时候,带declared的方法名才能获取所有范围的,否则只能获取public修饰的。比如:declaredField()和getField()。
Class userClass =Class.forName("com.me.test.reflect.User");
1.//获取属性,只能是public修饰的
Field field = userClass.getField("id");//否则找不到,异常//可以是任意范围
Field declaredField = userClass.getDeclaredField("pId");//public int com.me.test.reflect.User.id----private int//com.me.test.reflect.User.pId
System.out.println(field + "----" +declaredField);//只能获取public属性
Field[] fields =userClass.getFields();//所有属性
Field[] declaredF =userClass.getDeclaredFields();//[public int com.me.