关于反射的理解-浅谈反射

来源:互联网 发布:淘宝哪家店女装好看又便宜 编辑:程序博客网 时间:2024/06/07 11:42

1.反射的基石----->Class类

2,Java程序中的各个Java类属于同一类事物,描述这类事物的java类名就是Class。

3,Class类代表java类,它的各个实例对象对应各个类在内存中的字节码。一个类被加载到

内存中,占有一片存储空间,这个空间里面的内容就是类的字节码不同的类的字节码是不同的,所以

他们在内存中的内容是不同的。这一个个的空间可分别用一个个的对象来表示,这些对象具有相同的类型(Class类型)。

String s = "abc";
Class clz1 = s.getClass();
Class clz2 = String.class;
Class clz3=null;
try {
clz3 = Class.forName("java.lang.String");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

System.out.println(clz1==clz2);//true
System.out.println(clz1==clz3);//true
System.out.println(clz3==clz2);//true
System.out.println(new Date().getClass() ==clz1);//false同类的字节码是相同的,不同的类对应的字节码是不同的。但类型都是Class类。

System.out.println(s instanceof String);//true
System.out.println(clz1 instanceof Class);//true
System.out.println(new Date().getClass() instanceof Class);//true

//判断是否是基础类型isPrimitive()
System.out.println(clz1.isPrimitive());//false
System.out.println(int.class.isPrimitive());//true
System.out.println(int[].class.isPrimitive());//false
System.out.println(int[].class.isArray());//true
System.out.println(int.class==Integer.class);//false
System.out.println(int.class == Integer.TYPE);//true

4,反射

反射就是把Java类中的各种成分映射成相应的java类。例如,一个java类中用一个Class对象来表示,

一个类中的组成部分:成员变量,方法,构造方法,包等等信息也是一个个的java类来表示,比搜狐java

类的class类显然要提供一系列的方法,来获得起其中的变量,方法,构造方法,修饰符,包等信息。这些

信息就是用相应的实例对象来表示。他们是Field,,Method,Contructor,Package等等。

1,Constructor

Constructor 类代表某个类中的一个构造方法。

得到某个类所有的构造方法:

Constructor [] constructors = String.class.getConstructors();
Constructor [] constructors1 = Class.forName("java.lang.String").getConstructors();

得到某一个构造方法:

Constructor constructor = String.class.getConstructor(StringBuffer.class);

//创建一个实例。
//普通的实例
String s1 = new String(new StringBuffer("abc"));
//反射创建实例
String s2 = String.class.getConstructor(StringBuffer.class).newInstance(new StringBuffer("abc"));

Field类代表某个类的一个成员变量。

例如:

ReflectPoint 这个类中有了两个成员变量,x,y但x属于私有的,所以后面的操作会有所不一样。

两个成员方法,一个无参的,一个有两个参数的。

ReflectPoint reflectPoint  = new ReflectPoint(5, 7);

Field Y = reflectPoint.getClass().getField("y");
Object y = Y.get(reflectPoint);
System.out.println(y);
/*Field X = reflectPoint.getClass().getField("x");
Object x = X.get(reflectPoint);
System.out.println(x);
*/
Field X = reflectPoint.getClass().getDeclaredField("x");
X.setAccessible(true);
Object x = X.get(reflectPoint);
System.out.println(x);

2,一个小例子:将任意一个对象中的所有String类型的成员变量所对应字符串中内容的“b“改成”a“

public void changeValue(Object obj) throws  IllegalAccessException{

Field[] fields = obj.getClass().getFields();

for (Field field : fields) {
//这里要用==,因为比较的字节码,当然也是可以用equals的,用==号会显得技术牛。
if (field.getType()==String.class) {

String oldValue = (String) field.get(obj);
String newValue = oldValue.replace('b', 'a');
field.set(obj, oldValue);

}
}
}

3.Method类

Method 类代表某个类的一个成员方法

得到类中某一个方法
String s3 = "abcd";
Method charAt = String.class.getMethod("charAt", int.class);
//普通方法调用
char charAt2 = s3.charAt(1);
//反射方法调用
Object charAt3 = charAt.invoke(s3, 1);

如果传递给Method对象的invoke()方法的第一个参数为null.这有着什么样的意义呢?说明该Method对象对应的是一个静态方法!

4,数组的反射:

具有相同维数和元素类型的数据属于同一类型,具有相同的Class实例对象。


5,关于读取资源文件的方法和为位置:


/*InputStream is = new FileInputStream("src/com/koal/config.properties");
Properties pro = new Properties();
pro.load(is);
System.out.println(pro.get("className"));*/
/*InputStream ins = Test_Path.class.getClassLoader().getResourceAsStream("com/koal/config.properties");
Properties pro = new Properties();
pro.load(ins);
System.out.println(pro.get("className"));*/
InputStream ins = Test_Path.class.getResourceAsStream("config.properties");
Properties pro = new Properties();
pro.load(ins);
System.out.println(pro.get("className"));








0 0