Java SE 062 Class类、Method类及Field类的使用方式深度探析

(1)一个人只要自己不放弃自己,整个世界也不会放弃你.
(2)天生我才必有大用
(3)不能忍受学习之苦就一定要忍受生活之苦,这是多么痛苦而深刻的领悟
(4)做难事必有所得
(5)精神乃真正的刀锋
(6)战胜对手有两次,第一次在内心中.
(7)编写实属不易,若喜欢或者对你有帮助记得点赞+关注或者收藏哦~

Java SE 062 Class类、Method类及Field类的使用方式深度探析

1.反射要点

(1)要想使用反射,首先需要获得类对象所对应的Class类的类对象。
(2)要想使用反射,首先需要获得待处理类或对象所对应的Class对象。
Class对象能够洞悉到它所对应的目标类,或称目标对象里面的所有内容,比如:
(a)类的访问修饰符
(b)父类信息
(c)实现的接口信息
(d)有哪些成员变量与方法
(e)改变成员变量的内容
(f)调用类的成员方法
(3)一个Class对象对应的是一个类的信息。
(4)一个Method对象对应的是一个方法的信息。
(5)一个Field对象对应的是一个属性的信息。

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

2.1使用Class类的静态方法forName

Class.forName(“java.lang.string”);

2.2使用类的.class方法

String.class;

2.3使用对象的getClass()方法

String s = “aa”; Class<?> classType = s.getClass();

3.如何来生成一个对象

3.1classType.newInstance();

(1)创建一个新的,Class对象代表类的一个实例,这个类是被实例化是通过一个new 的表达式并且使用一个空的参数列表形式。
(2)即:classType.newInstance();==> new Customer();
(3)注意参数是空的。即这个类的构造方法不接收参数,那我们就可以使用这种方式去生成
(4)但是反过来,如果构造方法接收参数,我们就没法用这种方式去生成对象。

3.2如果构造方法接收参数,在反射中应该如何生成对象呢?

(1)要想生成一个对象,必然需要通过类的构造方法去生成,反射里面存在Constructor这样一个类,这个类代表构造方法所对应的一个Constructor对象。可以通过它提供的方法去生成带参数构造方法的类对象。
(2)如何获得Constructor这样一个类对象呢,通过Class对象去获得。

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

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

Class<?> classType = String.class; 
Object obj = classType.newInstance();

4.2先获得Class对象,然后通过该对象获得对应的Consructor对象,再通过该Constructor对象的newInstance()方法生成。

Class<?> classType = Customer.class; 
Constructor cons = classType.getConstructor(new Class[]{});
Object obj = cons.newInstance(new Object[]{});

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

Class<?> classType = Customer.class; 
Constructor cons = classType.getConstructor(new Class[]{String.class,int.class});
Object obj = cons.newInstance(new Object[]{“zhangsan”,22});

5.功能实战

5.1功能需求

定义一个方法,完成这样一个功能,接收一个Customer类型的一个对象,然后将对象的属性拷贝出来,生成一个新的对象,然后将新的对象拷回来。相当于实现一个对象的拷贝。

5.2传统解决问题的方式

先有一个Customer对象,然后再去生成一个Customer对象,然后调用新生成对象的set方法,同时调用已有对象的get方法,把get的值set到得到的新对象里面。

5.3使用反射来实现对象的拷贝

5.3.1定义需要拷贝的类
package com.javareview.refelect.theclass;

public 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;
	}
}
5.3.2实现对象属性值拷贝
package com.javareview.refelect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class CopyCustomer {
	/**
	 * 对象拷贝
	 * 定义一个方法,完成这样一个功能,接收一个Customer类型的一个对象,然后将对象的属性拷贝出来,生成一个新的对象,然后将新的对象拷回来。相当于实现一个对象的拷贝。
	 * @param object
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public Object copyObj(Object object) {
		//s1.获取对象所对应的Class对象(获得一个类对象所对应的Class对象的第三种方式)
		Class<?> classType = object.getClass();
		System.out.println(classType.getName());
		//s2.获取该对象的构造方法对象
		try {
			Constructor constructor = classType.getConstructor(new Class[] {String.class,int.class});
			//s3.生成对象实例(Constructor类对象的newInstance()去生成一个带参数的指定类的实例)
			Object obj = constructor.newInstance(new Object[]{"hello",3});
			//s3.1以上两行代码等价于下面一行代码,但是这句代码无法解决如果构造方法带参数这个问题。它只能解决不带参数的方式生成对象。
			//Object obj2 = classType.newInstance();
			//s4.构建拷贝的目标对象
			Object objectCopy = classType.getConstructor(new Class[]{}).newInstance(new Object[]{});
			//s5.获得对象的所有属性或成员变量
			Field[] fields = classType.getDeclaredFields();
			//s6.循环拷贝
			for(Field field: fields) {
				//6.1获取属性名
				String name = field.getName();
				//6.2将属性的首字母转换为大写
				String firstLetter = name.substring(0,1).toUpperCase();
				String getMethodName = "get"+firstLetter+name.substring(1);
				String setMethodName = "set"+firstLetter+name.substring(1);
				//6.3获取某方法的get方法对象(获取方法名对应的Method对象)
				Method getMethod = classType.getMethod(getMethodName, new Class[] {});
				//6.4获取某方法的set方法对象
				Method setMethod = classType.getMethod(setMethodName, new Class[] {field.getType()});
				//6.5通过反射调用get方法获取传入该对象的值
				Object value = getMethod.invoke(object,new Object[] {});
				//6.6通过反射调用对象的set方法,将对象的值通过新对象的set方法设置进去
				setMethod.invoke(objectCopy, new Object[] {value});
			}
			System.out.println(obj);
			System.out.println(objectCopy);
			return objectCopy;
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return null;
	}
}
5.3.3对象拷贝测试
package com.javareview.refelect.test;

import com.javareview.refelect.CopyCustomer;
import com.javareview.refelect.theclass.Customer;

/**
 * 对象拷贝测试
 * @author xiongjie
 *
 */
public class CustomerTest {
	public static void main(String[] args) {
		//s1.创建需要拷贝的对象
		Customer customer = new Customer("xiongjie",23);
		customer.setId(1L);
		//s2.拷贝对象
		CopyCustomer copyCustomer = new CopyCustomer();
		Customer customerCopy = (Customer)copyCustomer.copyObj(customer);
		//s3.显示拷贝后对象的值
		System.out.println(customerCopy.getId()+"  "+customerCopy.getName()+"  "+customerCopy.getAge());
	}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值