(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());
}
}