黑马程序员----Class类、反射(Reflect)

来源:互联网 发布:什么软件可以看美股 编辑:程序博客网 时间:2024/05/16 11:16
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
一.Class 类:
Class 代表java类,
Class cls1 = Date.class   //字节码1;
Class cls2 = Person.class //字节码2;


得到字节码对应的实例对象:
1、类名.class
2、对象.class
3、Class。forName("类名");


Class.gotName(); 返回字节码,分两种方式:
1.java 虚拟机中已经存在该类的字节码,直接返回
2.Java 虚拟机中没有,则调用类加载器加载,将返回的字节码存入Java虚拟机中。


数组类型的Class实例对象
Class.isArray();


二:反射
反射就是把Java类中的各种成分映射成为相应的Java类。


反射就是:
1.如果我知道一个类的名称/或者它的一个实例对象, 我就能把这个类的所有方法和变量的信息找出来(方法名,变量名,方法,修饰符,类型,方法参数等等所有信息)。
2.如果我还明确知道这个类里某个变量的名称,我还能得到这个变量当前的值。
2.当然,如果我明确知道这个类里的某个方法名+参数个数类型,我还能通过传递参数来运行那个类里的那个方法。


1、构造函数的反射
String.class.getConstructor(StringBuffer.class):表示获取StringBuffer类下的构造函数,并且是接收一个参数的构造方法,通过参数个数和类型来获取对应的构造函数。

Constructor[] constructors = Class.getName("java.lang.String").getConstructors(); 返回一个包含某些 Constructor 对象的数组,这些对象反映此 Class 对象所表示的类的所有公共构造方法。


创建实例对象:
通常方式:String str = new String(new StringBuffer("asd"));
反射方式:String str = constructor.newInstance(new StringBuffer("asd"));


2、成员变量的反射:Field

ReflectPoint pt1 = new ReflectPoint(3, 5);

Field fieldY = pt1.getClass().getField("y");
//fieldY代表类字节码下面的变量y,并不是pt1对象的y,所以filedY并不是5.要用fieldY去取某个对象上的值。
//fieldY.get(对象);获取某个对象上的变量y的值。
System.out.println(fieldY.get(pt1));

//Field fieldX = pt1.getClass().getField("x");//报错,原因是x是私有的,找不到。
Field fieldX = pt1.getClass().getDeclaredField("x");//不管变量是否私有,只要定义就会获取。
//System.out.println(fieldX.get(pt1));//上面改完后,这里又出现错误,无法获取私有的数据。
fieldX.setAccessible(true);//设置可以访问,暴力反射。
System.out.println(fieldX.get(pt1));

练习:改变对象中所有String类型的值中的a改为b
private static void changStringValue(Object obj) throws Exception {
//获取指定对象的类的所有可见的成员变量。
Field[] fields = obj.getClass().getFields();
for(Field field : fields){
System.out.println(field);//输出验证一下。
if(field.getType() == String.class){//此处用==而不用equals(),因为是同一份字节码。
String oldValue = (String) field.get(obj);
String newValue = oldValue.replace('a', 'b');
field.set(obj, newValue);
}

}
}


3、方法反射:Method
Method 类代表某个类中的一个成员方法。

(1)
/**传统方法
String str = "abc";
str.charAt(2);
*/
//反射方法
Method mycharAt = Class.getName("java.lang.String").getMethod("charAt",int.class);//


System.out.println(mycharAt.invoke(str,2));//invoke(null,2);第一个参数如果为null,则表示为静态方法


(2)用反射方式执行某个类中的main方法


/*
传统方式
//Test.main(new String[]{"as","234"});
*/


//反射方式
Method method = Class.forName(className).getMethod("main",String[].class);//className类的string表示  
method.invoke(null,new Object[]{new String[]{"as","234"}});  
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------详细请查看:www.itheima.com
0 0
原创粉丝点击