java反射机制(一)—— 利用反射机制实例化对象

时间:2021-11-08 09:20:49

一、Java有着一个非常突出的动态相关机制:Reflection,用在Java身上指的是我们可以于运行时加载、探知、使用编译期间完全未知的classes。换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。(度娘文库是这么说的)


二、这篇文章主要介绍一下通过反射机制去实例化一个类的对象,然后调用其方法。本文主要介绍两种方式,第一种就是通过构造函数来实例化,第二种就是通过Class<T>类的newnstance()方法进行实例化,下面我就通过代码来展示:

1、首先我建了一个Person类作为测试用的:

package com.reflect.test;

/**
* @author 林楷鹏
* @description 测试用的
* @create 2014-11-27下午9:34:00
*
*/
public class Person {

private int age;
private String name;

public Person() {

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

public void setAge(int age) {
this.age = age;
}

public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
}


2、通过构造函数:

package com.reflect.test;

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

/**
* @author 林楷鹏
* @description 反射机制,通过构造函数实例化对象
* @create 2014-11-27下午9:32:05
*
*/
public class ReflectConstructor {


public static void main(String[] args) {
Person person = new Person();
try {
Class<?> cls = Class.forName(person.getClass().getName());
//参数类型
Class<?>[] params = {Integer.TYPE, String.class};
//参数值
Object[] values = {15, "kroc"};
//构造有两个参数的构造函数
Constructor<?> constructor = cls.getDeclaredConstructor(params);
//根据构造函数,传入值生成实例
Object object = constructor.newInstance(values);
Method getAge = cls.getDeclaredMethod("getAge");
Method getName = cls.getDeclaredMethod("getName");
System.out.println("getAge = " + (Integer)getAge.invoke(object));
System.out.println("getName = " + (String)getName.invoke(object));
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("ClassNotFoundException");
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}
可以看到代码中,以下两行是比较重要的,第一行是通过参数个数去获取一个构造函数,记得这里传的参数的个数和类型要跟Person里面构造函数里面的相符,而参数类型也要和参数值values的类型一样,我这里就封装成params和values一起传进去

//构造有两个参数的构造函数
Constructor<?> constructor = cls.getDeclaredConstructor(params);
//根据构造函数,传入值生成实例
Object object = constructor.newInstance(values);

运行结果如下:

java反射机制(一)—— 利用反射机制实例化对象



3、第二种方式是通过Class<T>类的newnstance()方法进行初始化:

package com.reflect.test;

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


/**
* @author 林楷鹏
* @description 反射机制,通过newInstance()实例化对象
* @create 2014-11-27下午9:41:01
*
*/
public class ReflectMethod {


public static void main(String[] args) {
Person person = new Person();
try {
Class<?> cls = Class.forName(person.getClass().getName());
//生成实例,调用默认无参构造函数
Object object = cls.newInstance();
Method setName = cls.getDeclaredMethod("setName", String.class);
Method setAge = cls.getDeclaredMethod("setAge", Integer.TYPE);
setName.invoke(object, "KrocLin");
setAge.invoke(object, 20);
Method getAge = cls.getDeclaredMethod("getAge");
Method getName = cls.getDeclaredMethod("getName");
System.out.println("getAge = " + (Integer)getAge.invoke(object));
System.out.println("getName = " + (String)getName.invoke(object));
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("ClassNotFoundException");
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}
代码可以知道,其实用newInstance()是调用Person的默认无参构造函数的,所以本质上还是跟上一种方式一样。

运行结果:

java反射机制(一)—— 利用反射机制实例化对象


三、关于反射机制,可以做的事情还有很多,上面我为了简单展示就类似于getName这些方法名什么的都写死了,其实还可以通过反射去获取方法名,包括方法的返回类型啊、抛出异常等等都可以通过反射机制去得到。以后有时间就再写一些关于java反射机制的文章分享下,对于这个如果哪里写错了或者有什么更好的建议麻烦评论交流。