您的位置:首页 > 编程语言 > Java开发

(JAVA自学笔记)反射技术

2013-01-15 20:15 393 查看
day:20130114(包引入的快捷键 Ctrl + Alt + o)

Class:代表一类什么样的事物。Java类用于描述一类事物的共性,该类事物有什么属性,至于这个属性的值是什么,则是由这个类的实例对象来确定的,不同的实例对象有不同的属性值。Java程序中的各个Java类,他们属于同一类事物,描述这类事物的Java类的名字就是Class。要注意与小写class关键字的区别。Class类描述了类的名字,类的访问属性,类所属于的包名,字段名称的列表,方法名称的列表,等等。学习反射,首先要明白Class这个类。Person类代表人,它的实例对象就是张三,李四这样一个个具体的人,Class类代表Java类,它的实例对象分别对应各个类在内存中的字节码。例如,Person类的字节码等等。一个类被类加载器加载到内存中,占用一片存储空间,这个空间里面的内容就是类的字节码,不同的类的字节码是不同的,所以他们在内存中的内容是不同的,这一个个的空间可分别用一个个的对象来表示,这些对象显然具有相同的类型,这个类型是Class类型。

如何得都字节码?

三种方法:1.类名.class,例如System.class

2.对象.getClass() 例如 new Date().getClass();

3.Class.forName(""),例如Class.forName("java.util.Date");

九个预定义的Class对象:八个基本类型加void。

数组类型的Class实例对象:Class.isArray();总之,只要在源程序中出现的类型,都拥有各自的实例对象,例如int[],void...

实例:

public class ReflectTest {

public static void main(String[] args) throws Exception{

// TODO Auto-generated method stub

String str1 = "abc";

Class cls1 = str1.getClass();

Class cls2 = String.class;

Class cls3 = Class.forName("java.lang.String");

System.out.println(cls1 == cls2);

System.out.println(cls1 == cls3);

System.out.println(cls1.isPrimitive());

System.out.println(int.class.isPrimitive());

System.out.println(int.class == Integer.class);

System.out.println(int.class == Integer.TYPE);

System.out.println(int[].class.isArray());

}

}

输出:

true

true

false

true

false

true

true

反射就是把Java类中的各种成分映射成相应的Java类。例如,一个JAVA类中用一个Class类的对象来表示,一个类中的组成部分:成员变量、方法、构造方法、包等信息也用一个个的JAVA类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示JAVA类的Class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,它们是Field,Method,Contructor,Package等等。一个类中的每个成员都可以用相应的反射API类的一个实例对象来表示,通过调用Class类的方法可以得到这些实例对象后,得到这些实例对象后有什么用,怎么用,就是反射的要点了。

反射会导致程序性能下降。

Constructor类

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

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

Constuctor[] constructor = Class.forName("java.lang.String")

得到某一个构造方法:

Constructor constructor = Class.forName("java.lang.String").getConstructor(StringBuffer.class);//获得方法时要用到类型

创建实例对象:

通常方式:String str = new String(new StringBuffer("abc"));

反射方式:String str = (String)constructor.newInstance(new StringBuffer("abc"));//调用获得的方法时要用到上面相同类型的实例对象

Class.newInstance()方法:

String obj = (String)Class.forName[]("java.lang.String").newInstance();

该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。

该方法内部的具体代码用到了缓存机制来保存默认构造方法的实例对象。

Field类

实例代码:

ReflectPoint.java:

public class ReflectPoint {

private int x;

public int y;

public String str1 = "ball";

public String str2 = "basketball";

public String str3 = "itcast";

public ReflectPoint(int x, int y) {

super();

this.x = x;

this.y = y;

}

@Override

public String toString(){

return str1 + ":" + str2 + ":" + str3;

}

}

ReflectTest.java:

import java.lang.String;

import java.lang.reflect.*;

public class ReflectTest {

public static void main(String[] args) throws Exception{

// TODO Auto-generated method stub

String str1 = "abc";

Class cls1 = str1.getClass();

Class cls2 = String.class;

Class cls3 = Class.forName("java.lang.String");

System.out.println(cls1 == cls2);

System.out.println(cls1 == cls3);

System.out.println(cls1.isPrimitive());

System.out.println(int.class.isPrimitive());

System.out.println(int.class == Integer.class);

System.out.println(int.class == Integer.TYPE);

System.out.println(int[].class.isArray());

//new String(new StringBuffer("abc"));

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

String str2 = (String)constructor1.newInstance(new StringBuffer("abc"));

System.out.println(str2.charAt(2));

ReflectPoint pt1 = new ReflectPoint(3,5);

Field fieldY = pt1.getClass().getField("y");

//fieldY的值是多少?fieldY不是对象身上的变量,而是类上,要用它去取某个对象上对应的值

System.out.println(fieldY.get(pt1));

Field fieldX = pt1.getClass().getDeclaredField("x");

fieldX.setAccessible(true);

System.out.println(fieldX.get(pt1));

System.out.println(pt1);

}

private static void changeStringValue(Object obj) throws Exception{

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

for(Field field:fields){

//if(field.getType().equals(String.class)){

if(field.getType() == String.class){

String oldValue = (String)field.get(obj);

String newValue = oldValue.replace('b','a');

field.set(obj,newValue);

}

}

}

}

输出:

false

true

true

c

5

3

ball:basketball:itcast
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: