javaSE学习笔记之反射

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014070705/article/details/46765547


反射:

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类型

 

猜你喜欢

转载自blog.csdn.net/u014070705/article/details/46765547