----------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流! --------
黑马程序员_java高级篇反射Day10
#java中的Class类#(String.class)
在了解反射之前,先来了解一下Class类,这个并不是新建一个类,我们常常定义类,如许多人,我们可以定义一个Person类,许多类也可以定义一个Class类,Class获得的对象可以包含此类的基本信息,如某个类的类名。
Class cls1=str.getClass();
System.out.println(cls1.isPrimitive());
如果我们在程序中定义了三个类,生成了三份字节码,那么我们用Class得到三个类的对象
有三种方法去获得字节码,以下所有的解释都是基于这三种:
1,Class c=String.class
2,String str=”abc”; str.getClass()
3,Class.forname(“java.lang.String”);
@对于3,我们要注意一下,一种是内存中已经存在了此字节码,可以直接得到,另一种是还未加载的,那我们会先加载字节码到内存,再得到字节码。@
#java中的反射#(依靠对象得到字节码)
@反射的定义
定义:反射就是把java类的各种成分,映射成相应的java类
一个java类用一个Class的对象来表示,一个类的组成部分,成员变量,方法,构造方法,包等信息也是一个个java类,就像飞机是一个类,其中的发动机,变速器,黑盒子都是一个个类,表示java类显然要提供一系列的方法没来获得其中的变量方法,构造方法,修饰符,包等信息。
@基于String简单的反射机制
步骤:
1 ,首先得到他的构造方法
2,用这个构造方法时,还的传一个StringBuffer的对象
3,输出
使用反射的机制实现新建字符串,效果如new String( new StringBuffer("abc"));
对于为什么建立反射机制?,首先得到他的构造方法,StringBuffer.class这是StringBuffer的字节码
注意getConstructor中可以传入可变参数,可变参数请参考文章《黑马程序员_java高级篇JDK1.5的新特性系列Day9》
Constructor cons1=String.class.getConstructor(StringBuffer.class);
//用这个构造方法时,还的传一个StringBuffer的对象
String strs=(String)cons1.newInstance(new StringBuffer("abc"));
System.out.println(strs);
@ Class.forName用于反射
这里怎样得到Filed,Method,怎样去修改配置文件中的属性值,这里的代码都涉及到了。
这里就不一一累赘的解释了,看源代码中的注释
//第三个
String str2=(String)Class.forName("java.lang.String").newInstance();
//反射filed,ReflectFiled这是我建的一个类,包含数字与最
ReflectFiled rf=new ReflectFiled(3,5,"a","b");
//f有好多对象,当我们在这新建rf时,我们可以到的rf的field
//当我们再一次建立field时,我们同样可以找到,注意如果取x有错,因为它是私有的
Field f=rf.getClass().getField("y");
//从某个对应的变量身上取值
int a=f.getInt(rf);
System.out.println(a);
Field f1=rf.getClass().getDeclaredField("x");
//这样设置可以使私有变量可以访问。
f1.setAccessible(true);
//从某个对应的变量身上取值
int b=f1.getInt(rf);
System.out.println(b);
Field[] f2=rf.getClass().getFields();
//这样设置可以使私有变量可以访问。
//暂时先将x改为public
//f2.setAccessible(true);
for(Field fie:f2)
{
if(fie.getGenericType().equals("String"))
{
fie.set("name", "2");
}
}
//从某个对应的变量身上取值
for(Field fie:f2)
{
//因为这里是同一份字节码,所以用==比“equals”更加简明
if(fie.getType()==(String.class))
{
String str3=(String)fie.get(rf);
fie.set(rf, "ouyang");
String str4=(String)fie.get(rf);
System.out.println(str3+":"+str4);
}
}
//反射有什么用呢?
//当我们用反射时,我们可以修改一些配置文件中的参数,这也是反射的机制之一。
//第四 method
// 用反射的方法怎么做如str.charAt()
//arg0对应方法名,arg1对应的表示我们到底想从重载的方法中选择哪一个呢
//我们平时写程序是靠参数实现的,每一个参数都用arg1来表示,arg1是一个class
//arg1就是我们所说的class可变参数
String str5="aa";
//得到方法
java.lang.reflect.Methodm=String.class.getMethod("charAt",int.class);
//作用于某个对象,当我们把str5改为null表示调用静态方法
System.out.println(m.invoke(str5,1));
//面向对象中面试常考的,就是我们所说的人关门的问题,
//如果你推了一下门,门关了,那门是呢关的吗?不是的你只是个门一个信号,
//关门动作实在门身上的,这就是所谓道德专家模式,谁有数据谁就是专家
// JDK1.4与JDK1.5的小差别
/*
* 由于jdk1.4是没有可变参数的,但我们传入的参数不知道是多少时,我们
* 要传入一个数组
*/
@反射与内存
反射需要缓存,会使程序的性能下降。
就是对于我们上面解释的三种反射方法
1,Class c=String.class
2,String str=”abc”; str.getClass()
3,Class.forname(“java.lang.String”);
2与3其实想比较,3比二省了一个步骤,其实3还是用的2,只是有封装了一层,里面用到了cache,对比一下:
(2)
Constructor cons1=String.class.getConstructor(StringBuffer.class);
//用这个构造方法时,还的传一个StringBuffer的对象
String strs=(String)cons1.newInstance(new StringBuffer("abc"));
System.out.println(strs);
(3)
String str2=(String)Class.forName("java.lang.String").newInstance();
当我们查看newInstance()源代码时,我们会发现里面有cache,它是将得到的字节码先存在内存中,在来获取。
----------------------ASP.Net+Android+IOS开发.Net培训、期待与您交流! --------