反射
(1)一个类中的每个成员都可以用相应的反射api类的一个实例对象来表示。反射就是把java类中的各种成分映射为相应的java类。
反射的第一大作用 用来实现框架。
注意反射并不只是jdk1.5才新加入的而在jak1.2的时候就已经有了。
反射基础Class类
java程序中的各个java类属于同一类事物,而这类事物的java类名就是Class。
Class不能通过new 的方式实例化,(Class classs1)class1它代表了内存中的字节码, 字节码通俗的说就是你写java程序中所使用到的类,一个类对应一个字节码也就是说对应 一个Class类型的数据如(Class classs1 Class classs2 Class classs3 ................)。
获取字节码的方法有类名.class/,对象.getclass ,Class.forName("java.lang.String")
注意这3种方式获取的同一个类的字节码都是获取的同一个。所以字节码在比较的时候最好用==而不推荐使用equals
如: String string="1";
System.out.print(String.class==string.getClass());
System.out.print(string.getClass()==Class.forName("java.lang.String")); 会输出2个true
其中forName方法的2中获取方式
1如果jvm有则返回字节码
2如果jvm还未加载 则用类加载器加载且缓存
在java中有9个预定义的Class实例对象其中包括8个基本的数据类型它们每个都对应一个Class对象和一个void.class
(2)关于Constructor类
Constructor 提供关于类的构造方法的信息以及对它的访问权限。
如得到某个类所有的构造方法Constructor [] constructors=Class.forName("java.lang.String").getConstructor ();
如得到某个类的某一个构造方法
Constructor constructor=Class.forName("java.lang.String").getConstructor (StringBuffer.class);
如创建对象(反射的方式)
Constructor<String>constructor=(Constructor<String>)Class.forName("java.lang.String").getConstructor (StringBuffer.class);
String st=constructor.newInstance(new StringBuffer("123"));
System.out.print(st);
注意代码中的newInstance与Constructor类中的newInstance的区别在于Class类中的newInstance会直接调用类中空的构造方法,而Constructor中的newInstance则可以赋值来选择性的调用类的构造方法。
如成员变量的反射
public class ReflectPoint {
private Date birthday = new Date();
private int x;
public int y;
public ReflectPoint(int x, int y) {
super();
this.x = x;
this.y = y;
}}
public class ReflectTest {
public static void main(String[] args) throws Exception
ReflectPoint pt1 = new ReflectPoint(3,5);
Field fieldY = pt1.getClass().getField("y");
//fieldY的值是多少?是5,错!fieldY不是对象身上的变量,而是类上,要用它去取某个对象上对应的值
System.out.println(fieldY.get(pt1));
Field fieldX = pt1.getClass().getDeclaredField("x");
fieldX.setAccessible(true);//设置为可以访问私有的 System.out.println(fieldX.get(pt1));
(3)反射的调用一个类String startingClassName = args[0]; Method mainMethod = Class.forName(startingClassName).getMethod("main", String[].class);
注意为了兼容jdk1.4 在给main方法传递参数的时候要先将其包装也就是只允许有一个参数
//mainMethod.invoke(null, new Object[]{new String[]{"111","222","333"}});
mainMethod.invoke(null, (Object)new String[]{"111","222","333"});