一、静态加载 VS 动态加载
1.编译时加载的类都是静态加载类,运行时加载的类为动态加载类
2.new出来的都是静态加载类,在编译时 需要实例的对象必须存在。
3.动态加载类通过Class.forName(”类的全路径名”)就可以加载类,返回的是加载类的类类型,通过该类的对象newInstance方法,就可以获得这个对象的实例
二、Java反射机制
Java反射机制——获取成员变量&构造函数
一、成员变量是java.lang.reflect.Field的对象
1、Field类封装了关于成员变量的操作
2、Field[] fs = c.getFields()方法获取所有public的成员变量Field[]信息
3、c.getDeclaredFields获取的是该类自己声明的成员变量信息
4、field.getType()获得成员类型的类类型
5、field.getName()获得成员的名称
二、构造函数是java.lang.Constructor类的对象
1、通过Class.getConstructor()获得Constructor[]所有公有构造方法信息
2、建议getDeclaredConstructors()获取自己声明的构造方法
3、Constructor.getName():String
4、Constructor.getParameterTypes():Class[]
成员变量也是对象,是java.lang.reflect.Field的对象;
三、方法的反射:
- 方法名称加参数列表可以唯一确定一个方法
- 通过方法对象来实现方法的功能,即把实例对象当成参数传给方法对象
Here is an example:
There is a class A:
class A{void printInfo(String s1, String s2){System.out.println(s1 + s2);}}
Implement the class:
A a = new A();
Class c = a.getClass();
Method m = c.getMethod("printInfo", String.class, String.class);
//getMethod方法只能获得public方法
//getDeclaredMethod方法能获得所有自己声明的方法
//you can write the above code like following:
Method m = c.getMethod("printInfo", new Object[]{String.class,String.class});
Object o = m.invoke(a, "Hello ", "World!");//Here, o = null
//You can also write like:
Object o = m.invoke(a, new Object[]{"Hello ","World!"});
//The above code just like:
a.printInfo("Hello ","World!");
四、Java反射机制——通过反射了解集合泛型的本质
1:反射的操作都是编译之后的操作;就是运行阶段
2:java中集合的泛型是防止错误输入的;只在编译阶段有效,只要绕过编译就无效啦
我们可以通过方法的反射来操作,绕过编译
eg:
ArrayList list1=new ArrayList();
ArrayList<String> list2=new ArrayList<String>();
Class c1=list1.getClass();
Class c2=list2.getClass();
System.out.print(c1==c2);//true
Method m=c2.getMethod("add",Object.class);
m.invoke(list2,20);//向list2集合中添加一个int 型的值;绕过编译
当然是不能直接foreach list2集合的,会报类型转换错误