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

javaSE学习笔记之反射

2015-07-05 20:48 477 查看
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

反射:

1. 反射(发生在运行时期)作用:

a) 判断任意一个对象所属的类

b) 构造任意一个对象

c) 判断任意一个类所具有的成员变量和方法

d) 在运行时调用一个对象的方法

2.在JDK中,主要由以下类来实现Java反射机制,这些类都位于java.lang.reflect包中

1) Class类:代表一个类。

2) Field 类:代表类的成员变量(成员变量也称为类的属性)。

3) Method类:代表类的方法。

4) Constructor 类:代表类的构造方法。

5) Array类:提供了动态创建数组,以及访问数组的元素的静态方法

3. 要想使用反射,首先需要获得待处理类或对象所对应的 Class 对象。

4. 获取某个类或某个对象所对应的Class 对象的常用的 3 种方式:

a) 使用 Class 类的静态方法 forName :Class.forName(“java.lang.String”);

b) 使用类的.class 语法:String.class;

c) 使用对象的 getClass() 方法:String s = “aa”; Class<?> clazz = s.getClass();

5. 若想通过类的不带参数的构造方法来生成对象,我们有两种方式:

a) 先获得 Class 对象,然后通过该 Class 对象的 newInstance()方法直接生成即可:

Class<?> classType =String.class;

Object obj =classType.newInstance();

b) 先获得 Class 对象,然后通过该对象获得对应的Constructor 对象,再通过该 Constructor

对象的newInstance()方法生成:

Class<?> classType =Customer.class;

Constructor cons =classType.getConstructor(new Class[]{});

Object obj = cons.newInstance(newObject[]{});

6. 若想通过类的带参数的构造方法生成对象,只能使用下面这一种方式:

Class<?> classType =Customer.class;

Constructor cons =classType.getConstructor(new Class[]{String.class, int.class});

Object obj = cons.newInstance(newObject[]{“hello”, 3});

public class ReflectTester
{
// 该方法实现对Customer对象的拷贝操作
public Object copy(Object object) throws Exception
{
Class<?> classType = object.getClass();

Object objectCopy = classType.getConstructor(new Class[] {})
.newInstance(new Object[] {});

// 获得对象的所有成员变量

Field[] fields = classType.getDeclaredFields();

for (Field field : fields)
{
String name = field.getName();

String firstLetter = name.substring(0, 1).toUpperCase();// 将属性的首字母转换为大写

String getMethodName = "get" + firstLetter + name.substring(1);
String setMethodName = "set" + firstLetter + name.substring(1);

Method getMethod = classType.getMethod(getMethodName,
new Class[] {});
Method setMethod = classType.getMethod(setMethodName,
new Class[] { field.getType() });

Object value = getMethod.invoke(object, new Object[] {});

setMethod.invoke(objectCopy, new Object[] { value });
}

// 以上两行代码等价于下面一行
// Object obj2 = classType.newInstance();

// System.out.println(obj);

return objectCopy;
}

public static void main(String[] args) throws Exception
{
Customer customer = new Customer("Tom", 20);
customer.setId(1L);

ReflectTester test = new ReflectTester();

Customer customer2 = (Customer) test.copy(customer);

System.out.println(customer2.getId() + "," + customer2.getName() + ","
+ customer2.getAge());
}
}

class Customer
{
private Long id;

private String name;

private int age;

public Customer()
{

}

public Customer(String name, int age)
{
this.name = name;
this.age = age;
}

public Long getId()
{
return id;
}

public void setId(Long id)
{
this.id = id;
}

public String getName()
{
return name;
}

public void setName(String name)
{
this.name = name;
}

public int getAge()
{
return age;
}

public void setAge(int age)
{
this.age = age;
}
}
例题详解:

• ReflectTester类有一个copy(Object object)方法,这个方法能够创建一个和参数object 同样类型的对象,然后把object对象中的所有属性拷贝到新建的对象中,并将它返回

• 这个例子只能复制简单的JavaBean,假定JavaBean 的每个属性都有public 类型的getXXX()和setXXX()方法。



• ReflectTester 类的copy(Object object)方法

依次执行以下步骤

• (1)获得对象的类型:

Class classType=object.getClass();

System.out.println("Class:"+classType.getName());

• 在java.lang.Object 类中定义了getClass()方法,因此对于任意一个Java对象,都可以通过此方法获得对象的类型。Class类是Reflection API中的核心类,它有以下方法

getName():获得类的完整名字。

getFields():获得类的public类型的属性。

getDeclaredFields():获得类的所有属性。

getMethods():获得类的public类型的方法。

getDeclaredMethods():获得类的所有方法。

getMethod(String name, Class[]parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。

• getConstructors():获得类的public类型的构造方法。

• getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。

• newInstance():通过类的 不带参数的构造方法创建这个类的一个对象。

• (2)通过默认构造方法创建一个新对象:

• Object objectCopy=classType.getConstructor(new Class[]{}).newInstance(new Object[]{});

• 以上代码先调用Class类的getConstructor()方法获得一个Constructor 对象,它代表默认的构造方法,然后调用Constructor对象的newInstance()方法构造一个实例。

• (3)获得对象的所有属性:

• Field fields[]=classType.getDeclaredFields();

• Class 类的getDeclaredFields()方法返回类的所有属性,包括public、protected、默认和private访问级别的属性

• (4)获得每个属性相应的getXXX()和setXXX()方法,然后执行这些方法,把原来对象的属性拷贝到新的对象中

• 在例程InvokeTester类的main()方法中,运用反射机制调用一个InvokeTester对象的add()和echo()方法

• add()方法的两个参数为int 类型,获得表示add()方法的Method对象的代码如下:

• Method addMethod=classType.getMethod("add",new Class[]{int.class,int.class});

• Method类的invoke(Object obj,Object args[])方法接收的参数必须为对象,如果参数为基本类型数据,必须转换为相应的包装类型的对象。invoke()方法的返回值总是对象,如 果实际被调用的方法的返回类型是基本类型数据,那么invoke()方法会把它转换为相应的包装类型的对象,再将其返回

• 在本例中,尽管InvokeTester 类的add()方法的两个参数以及返回值都是int类型,调用add Method 对象的invoke()方法时,只能传递Integer 类型的参数,并且

invoke()方法的返回类型也是Integer 类型,Integer类是int 基本类型的包装类:

• Object result=addMethod.invoke(invokeTester,new Object[]{new Integer(100),newInteger(200)});

• System.out.println((Integer)result); //result 为Integer类型

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