本文介绍了java反射内容、类如何加载以及反射的具体应用。
一、反射介绍
1、反射概述
- Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
- 对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
2、Java反射机制功能
主要提供了以下功能:
- 在运行时判断任意一个对象所属的类
- 在运行时构造任意一个类的对象
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时调用任意一个对象的方法
- 生成动态代理
Java中,反射是一种强大的工具。 它能够创建灵活的代码,这些代码可以在运行时装配,无需在组件之间进行源代表链接。 反射允许在编写与执行时,使程序代码能够接入装载到JVM中的类的内部信息,而不是源代码中选定的类协作的代码。 这使反射成为构建灵活的应用的主要工具。如果使用不当,反射的成本很高。
3、反射的应用场景
目前好多框架都会用到java的反射机制。比如struts2,sping,hibernate。 如果自己写一个类似的功能也是可以实现的,比如浏览器通过HTTP发送数据,而这些数据都是字符串,接受到这些字符串时, 可以通过反射去构造一个对象(通过拦截器做成框架的功能),这样就可以用对象的get和set方法了,而不用原始的getPeremter()方法。
二、类加载器
1、类的加载
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载、连接、初始化三步来实现对这个类进行初始化。
1)、加载
是指将class文件读入内存,并为之创建一个Class对象。 任何类被使用时系统都会建立一个Class对象。
2)、连接
该步骤有如下工作需要完成。
- 验证,是否有正确的内部结构,并和其他类协调一致
- 准备,负责为类的静态成员分配内存,并设置默认初始化值
- 解析,将类的二进制数据中的符号引用替换为直接引用
3)、初始化
类会在首次被“主动使用”时执行初始化,为类(静态)变量赋予正确的初始值。在Java代码中,一个正确的初始值是通过类变量初始化语句或者静态初始化块给出的。 初始化一个类包括两个步骤:
- 如果类存在直接父类的话,且直接父类还没有被初始化,则先初始化其直接父类
- 如果类存在一个初始化方法,就执行此方法
初始化接口并不需要初始化它的父接口。
2、类初始化时机
- 创建类的实例
- 访问类的静态变量,或者为静态变量赋值
- 调用类的静态方法
- 使用反射方式来强制创建某个类或接口对应的java.lang.Class对象
- 初始化某个类的子类
- 直接使用java.exe命令来运行某个主类
3、类加载器
1)、类加载器
负责将.class文件加载到内存中,并为之生成对应的Class对象。
2)、类加载器的组成
BootstrapClassLoader //根类加载器
ExtensionClassLoader //扩展类加载器
SysetmClassLoader //系统类加载器
4、类加载器的作用
1)、Bootstrap ClassLoader 根类加载器(引导类加载器)
也被称为引导类加载器,负责Java核心类的加载,比如System、String等。在JDK中JRE的lib目录下rt.jar文件中。
2)、Extension ClassLoader 扩展类加载器
负责JRE的扩展目录中jar包的加载。在JDK中JRE的lib目录下ext目录。
3)、Sysetm ClassLoader 系统类加载器
负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径。 通过这些描述可以知道常用的东西的加载都是由谁来完成的。
到目前为止已经知道把class文件加载到内存了,那么,如果仅仅站在这些class文件的角度,如何来使用这些class文件中的内容呢?这就是反射要研究的内容。
5、类加载器的委托机制
首先委托类加载器的父类去加载,如果父类无法加载则自己加载
当系统类加载器去加载一个类时,它首先会让上级去加载,即让扩展类加载器去加载类,扩展类加载器也会让它的上级引导类加载器去加载类。如果上级没有加载成功,那么再由自己去加载。例如自己写的Person类,一定是存放到CLASSPATH中,那么一定是由系统类加载器来加载。当系统类加载器来加载类时,它首先把加载的任务交给扩展类加载去,如果扩展类加载器加载成功了,那么系统类加载器就不会再去加载。这就是代理模式了。
扩展类加载器也会把加载类的任务交给它的“上级”,即引导类加载器,引导类加载器加载成功,那么扩展类加载器也就不会再去加载了。引导类加载器是用C语言写的,是JVM的一部分,它是最上层的类加载器了,所以它就没有“上级了”。它只负责去加载JDK中的类。
当扩展类加载器发现“上级”不能加载类,它就开始加载工作了,它加载的是lib\ext目录下的jar文件,当然,它也会加载失败,所以最终还是由系统类加载器在CLASSPATH中去加载Person,最终由系统类加载器加载到了Person类。
代理模式保证了JDK中的类一定是由引导类加载加载的!这就不会出现多个版本的类,这也是代理模式的好处。
6、自定义类加载器
也可以通过继承ClassLoader类来完成自定义类加载器,自定义类加载器的目的一般是为了加载网络上的类,因为这会让class在网络中传输,为了安全,那么class一定是需要加密的,所以需要自定义的类加载器来加载(自定义的类加载器需要做解密工作)。 ClassLoader加载类都是通过loadClass()方法来完成的,loadClass()方法的工作流程如下:
- 调用findLoadedClass()方法查看该类是否已经被加载过了,如果该没有加载过,那么这个方法返回null
- 判断findLoadedClass()方法返回的是否为null,如果不是null那么直接返回,这可以避免同一个类被加载两次
- 如果findLoadedClass()返回的是null,那么就启动代理模式(委托机制),即调用上级的loadClass()方法,获取上级的方法是getParent(),当然上级可能还有上级,这个动作就一直向上走
- 如果getParent().loadClass()返回的不是null,这说明上级加载成功了,那么就加载自己
- 如果上级返回的是null,这时loadClass()方法会调用本类的findClass()方法来加载类
这说明只需要重写ClassLoader的findClass()方法。 通过上面的分析,知道要自定义一个类加载器,只需要继承ClassLoader类,然后重写它的findClass()方法即可。 在findClass()方法中要完成的工作如下:
- 找到class文件,把它加载到一个byte[]中;
- 调用defineClass()方法,把byte[]传递给这个方法即可。
public class FileSystemClassLoader extends ClassLoader {
private String classpath;
public FileSystemClassLoader() {
}
public FileSystemClassLoader(String classpath) {
this.classpath = classpath;
}
@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
try {
byte[] datas = getClassData(name);
if (datas == null) {
throw new ClassNotFoundException("类没有找到:" + name);
}
return this.defineClass(name, datas, 0, datas.length);
} catch (IOException e) {
e.printStackTrace();
throw new ClassNotFoundException("类找不到:" + name);
}
}
private byte[] getClassData(String name) throws IOException {
name = name.replace(".", "\\") + ".class";
File classFile = new File(classpath, name);
return FileUtils.readFileToByteArray(classFile);
}
public static void main(String[] args) {
ClassLoader loader = new FileSystemClassLoader("F:\\classpath");
Class clazz = null;
Method method = null;
try {
clazz = loader.loadClass("com.win.reflect.User");
method = clazz.getMethod("setName", String.class);
String result = (String) method.invoke(null, "qdmmy6");
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
三、反射
反射就是通过class文件对象,去使用该文件中的成员变量,构造方法,成员方法。Class类:成员变量Field、构造方法Constructor、成员方法Method。
1、三种获取Class对象的方式
- Object类的getClass()方法
Person p = new Person();
Class c = p.getClass();
- 数据类型的静态属性class
Class c2 =Person.class;
任意数据类型都具备一个class静态属性,看上去要比第一种方式简单
- 将类名作为字符串传递给Class类中的静态方法forName即可
Class c3 = Class.forName("Person");
1)、示例
- 测试类
import lombok.Data;
@Data
public class Person {
private String name;
int age;
public String address;
public Person() {
}
private Person(String name) {
this.name = name;
}
Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
public void show() {
System.out.println("show");
}
public void method(String s) {
System.out.println("method " + s);
}
public String getString(String s, int i) {
return s + "---" + i;
}
private void function() {
System.out.println("function");
}
public String toString() {
return "Person [name=" + name + ", age=" + age + ", address=" + address + "]";
}
}
- 反射类
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
// 方式1
Person p = new Person();
Class c = p.getClass();
Person p2 = new Person();
Class c2 = p2.getClass();
System.out.println(p == p2);// false
System.out.println(c == c2);// true
// 方式2
Class c3 = Person.class;
// int.class;
// String.class;
System.out.println(c == c3);
// 方式3
// ClassNotFoundException
Class c4 = Class.forName("com.win.reflect.Person");
System.out.println(c == c4);
System.out.println(c + " " + c4);
}
}
- 运行结果
false
true
true
true
class com.win.reflect.Person class com.win.reflect.Person
2、Class
1、表示类
2)、Constructor
表示一个类中的构造方法
3)、Field
表示一个类中的成员变量
4)、Method
表示一个类中的成员方法
5)、Type
Type[ ] getActualTypeArguments() //获取真实参数
3、反射的应用
通过反射获取构造方法并使用
1)、获取构造方法
2)、创建对象
3)、通过反射获取成员变量并使用
1、获取所有成员
2、获取单个成员
3、修改成员的值
4)、通过反射获取成员方法并使用
4、示例
1)、测试类Person、City、TestInterface
- person
import lombok.Data;
/**
* @author alanchan
*
*/
@Data
public class Person {
private Long id;
public String name;
int age;
public String address;
Long salary;
long long1;
double aDouble;
Double aDouble1;
Integer integer;
Float aFloat1;
float aFloat;
boolean aBoolean;
Boolean aBoolean1;
short aShort;
byte aByte;
Byte aByte1;
char aChar;
public void show() {
System.out.println("show");
}
public void method(String s) {
System.out.println("method " + s);
}
public String getString(String s, int i) {
return s + "---" + i;
}
private void function() {
System.out.println("function");
}
private void getSomeThing() {
// do something
}
public Person() {
}
public Person(Long id) {
this.id = id;
}
private Person(String name) {
this.name = name;
}
Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(Long id, String name) {
this.name = name;
this.id = id;
}
public Person(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
}
- city
public class City {
}
- testinterface
public interface TestInterface {
}
2)、反射示例
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.junit.Before;
import org.junit.Test;
/**
* @author alanchan
*
*/
public class MyReflect {
public String className = null;
@SuppressWarnings("rawtypes")
public Class personClass = null;
/**
* 反射Person类
*
* @throws Exception
*/
@Before
public void init() throws Exception {
className = "org.druiddemo.Person";
personClass = Class.forName(className);
}
/**
* 获取某个class文件对象
*/
@Test
public void getClassName() throws Exception {
System.out.println(personClass);
}
/**
* 获取某个class文件对象的另一种方式
*/
@Test
public void getClassName2() throws Exception {
System.out.println(Person.class);
}
/**
* 创建一个class文件表示的实例对象,底层会调用空参数的构造方法
*/
@Test
public void getNewInstance() throws Exception {
System.out.println(personClass.newInstance());
}
/**
* 获取非私有的构造函数
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void getPublicConstructor() throws Exception {
Constructor constructor = personClass.getConstructor(Long.class, String.class);
Person person = (Person) constructor.newInstance(100L, "zhangsan");
System.out.println(person.getId());
System.out.println(person.getName());
}
/**
* 获得私有的构造函数
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void getPrivateConstructor() throws Exception {
Constructor con = personClass.getDeclaredConstructor(String.class);
con.setAccessible(true);// 强制取消Java的权限检测
Person person2 = (Person) con.newInstance("zhangsan");
System.out.println("**" + person2.getName());
}
/**
* 访问非私有的成员变量
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void getNotPrivateField() throws Exception {
Constructor constructor = personClass.getConstructor(Long.class, String.class);
Object obj = constructor.newInstance(100L, "zhangsan");
Field field = personClass.getField("name");
field.set(obj, "lisi");
System.out.println(field.get(obj));
}
/**
* 访问私有的成员变量
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void getPrivateField() throws Exception {
Constructor constructor = personClass.getConstructor(Long.class);
Object obj = constructor.newInstance(100L);
Field field2 = personClass.getDeclaredField("id");
field2.setAccessible(true);// 强制取消Java的权限检测
field2.set(obj, 10000L);
System.out.println(field2.get(obj));
}
/**
* 获取非私有的成员函数
*/
@SuppressWarnings({ "unchecked" })
@Test
public void getNotPrivateMethod() throws Exception {
System.out.println(personClass.getMethod("toString"));
Object obj = personClass.newInstance();// 获取空参的构造函数
Method toStringMethod = personClass.getMethod("toString");
Object object = toStringMethod.invoke(obj);
System.out.println(object);
}
/**
* 获取私有的成员函数
*/
@SuppressWarnings("unchecked")
@Test
public void getPrivateMethod() throws Exception {
Object obj = personClass.newInstance();// 获取空参的构造函数
Method method = personClass.getDeclaredMethod("getSomeThing");
method.setAccessible(true);
Object value = method.invoke(obj);
System.out.println(value);
}
@Test
public void otherMethod() throws Exception {
// 当前加载这个class文件的那个类加载器对象
System.out.println(personClass.getClassLoader());
// 获取某个类实现的所有接口
Class[] interfaces = personClass.getInterfaces();
for (Class class1 : interfaces) {
System.out.println(class1);
}
// 反射当前这个类的直接父类
System.out.println(personClass.getGenericSuperclass());
/**
* getResourceAsStream这个方法可以获取到一个输入流,这个输入流会关联到name所表示的那个文件上。
*/
// path
// 不以’/'开头时默认是从此类所在的包下取资源,以’/'开头则是从ClassPath根下获取。其只是通过path构造一个绝对路径,最终还是由ClassLoader获取资源。
System.out.println(personClass.getResourceAsStream("/log4j.properties"));
System.out.println(personClass.getResourceAsStream("log4j.properties"));
// 判断当前的Class对象表示是否是数组
System.out.println(personClass.isArray());
System.out.println(new String[3].getClass().isArray());
// 判断当前的Class对象表示是否是枚举类
System.out.println(personClass.isEnum());
System.out.println(Class.forName("org.druiddemo.City").isEnum());
// 判断当前的Class对象表示是否是接口
System.out.println(personClass.isInterface());
System.out.println(Class.forName("org.druiddemo.TestInterface").isInterface());
}
}
-运行结果
sun.misc.Launcher$AppClassLoader@2503dbd3
class java.lang.Object
null
null
false
true
false
false
false
true
10000
**zhangsan
lisi
null
class org.druiddemo.Person
class org.druiddemo.Person
public java.lang.String org.druiddemo.Person.toString()
Person(id=null, name=null, age=0, address=null, salary=null, long1=0, aDouble=0.0, aDouble1=null, integer=null, aFloat1=null, aFloat=0.0, aBoolean=false, aBoolean1=null, aShort=0, aByte=0, aByte1=null, aChar=
5、示例-查看信息并赋值
1)、测试类Person
import lombok.Data;
/**
* @author alanchan
*
*/
@Data
public class Person {
private String name;
int age;
public String address;
Long salary;
long long1;
double aDouble;
Double aDouble1;
Integer integer;
Float aFloat1;
float aFloat;
short aShort;
boolean aBoolean;
Boolean aBoolean1;
byte aByte;
Byte aByte1;
char aChar;
public void show() {
System.out.println("show");
}
public void method(String s) {
System.out.println("method " + s);
}
public String getString(String s, int i) {
return s + "---" + i;
}
private void function() {
System.out.println("function");
}
public Person() {
}
private Person(String name) {
this.name = name;
}
Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
}
2)、反射类-查看测试类的属性、方法和构造函数
1、获取测试类Person的三种方式
@Test
public void testgetClass() throws ClassNotFoundException {
// 方式1
Person p = new Person();
Class c = p.getClass();
Person p2 = new Person();
Class c2 = p2.getClass();
System.out.println(p == p2);// false
System.out.println(c == c2);// true
// 方式2
Class c3 = Person.class;
// int.class;
// String.class;
System.out.println(c == c3);
// 方式3
// ClassNotFoundException
Class c4 = Class.forName("org.druiddemo.Person");
System.out.println(c == c4);
System.out.println(c + " " + c4);
}
- 运行结果
false
true
true
true
class org.druiddemo.Person class org.druiddemo.Person
2、查看测试类Person的构造函数并赋值
@Test
public void testConstructor() throws Exception {
Class clazz = Class.forName("org.druiddemo.Person");
// 获取构造函数
// 1、获取public构造函数
System.out.println("1、获取public构造函数,如下:");
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor.getName());
}
System.out.println("2、获取所有构造函数,如下:");
// 2、获取所有构造函数
Constructor[] constructors1 = clazz.getDeclaredConstructors();
for (Constructor constructor : constructors1) {
System.out.println("2.1获取所有构造函数的参数类型,构造函数如下:");
System.out.print(constructor.getName() + " (");
// 2.1获取所有构造函数的参数类型
Class[] parameterTypes = constructor.getParameterTypes();
int typeleng = 0;
for (Class cla : parameterTypes) {
typeleng += 1;
System.out.print(cla.getName());
if (typeleng != parameterTypes.length) {
System.out.print(",");
}
}
System.out.println(") ");
}
// 根据构造函数的类型创建实例
System.out.println("3、根据构造函数的类型创建实例,如下:");
Constructor[] constructors2 = clazz.getDeclaredConstructors();
for (Constructor constructor : constructors2) {
System.out.println("3、根据构造函数的类型创建实例,构造函数如下:");
System.out.print(constructor.getName() + ":");
// 3、根据构造函数的类型创建实例
Class[] parameterTypes = constructor.getParameterTypes();
Object object = null;
constructor.setAccessible(true);
// 3.1创建无参构造函数
if (parameterTypes.length == 0) {
object = clazz.newInstance();
System.out.println("无参构造函数的toString:" + object.toString());
} else {
// 3.2有参构造函数,根据参数的类型进行构造
// 设置构造函数的参数值
Object[] parameterValues = new Object[parameterTypes.length];
for (int i = 0; i < parameterTypes.length; i++) {
Class cla = parameterTypes[i];
if (cla.getSimpleName().equals("int") || cla.getSimpleName().equals("Integer")) {
parameterValues[i] = 123;
}
if (cla.getSimpleName().equals("String")) {
parameterValues[i] = "testing";
}
if (cla.getSimpleName().equals("Double") || cla.getSimpleName().equals("double")) {
parameterValues[i] = 34.5;
}
if (cla.getSimpleName().equals("Long") || cla.getSimpleName().equals("long")) {
parameterValues[i] = 234l;
}
if (cla.getSimpleName().equals("Float") || cla.getSimpleName().equals("float")) {
parameterValues[i] = 234f;
}
if (cla.getSimpleName().equals("Boolean") || cla.getSimpleName().equals("boolean")) {
parameterValues[i] = true;
}
if (cla.getSimpleName().equals("Byte") || cla.getSimpleName().equals("byte")) {
parameterValues[i] = 3;
}
if (cla.getSimpleName().equals("char") || cla.getSimpleName().equals("Char")) {
parameterValues[i] = "c";
}
if (cla.getSimpleName().equals("Short") || cla.getSimpleName().equals("short")) {
parameterValues[i] = 5;
}
}
object = constructor.newInstance(parameterValues);
System.out.println("有参构造函数的toString:" + object);
}
// 3.2有参构造函数,根据参数的类型进行构造
for (Class cla : parameterTypes) {
System.out.print(" param:name-->" + cla.getName());
System.out.print(" param:typeName-->" + cla.getTypeName());
System.out.print(" param:simpleName-->" + cla.getSimpleName());
System.out.println(" param:modifiers-->" + cla.getModifiers());
}
}
}
- 运行结果
1、获取public构造函数,如下:
org.druiddemo.Person
org.druiddemo.Person
2、获取所有构造函数,如下:
2.1获取所有构造函数的参数类型,构造函数如下:
org.druiddemo.Person (java.lang.String)
2.1获取所有构造函数的参数类型,构造函数如下:
org.druiddemo.Person ()
2.1获取所有构造函数的参数类型,构造函数如下:
org.druiddemo.Person (java.lang.String,int)
2.1获取所有构造函数的参数类型,构造函数如下:
org.druiddemo.Person (java.lang.String,int,java.lang.String)
3、根据构造函数的类型创建实例,如下:
3、根据构造函数的类型创建实例,构造函数如下:
org.druiddemo.Person:有参构造函数的toString:Person(name=testing, age=0, address=null, salary=null, long1=0, aDouble=0.0, aDouble1=null, integer=null, aFloat1=null, aFloat=0.0, aShort=0, aBoolean=false, aBoolean1=null, aByte=0, aByte1=null, aChar=
3、查看测试类Person的方法并赋值
Byte、byte、short赋值测试没通过
@Test
public void testMethod() throws Exception {
Class clazz = Class.forName("org.druiddemo.Person");
Object object = clazz.newInstance();// 构造无参对象
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
method.setAccessible(true);
// 获取所有的方法名称、参数类型及返回数据类型
System.out.print(method.getReturnType() + " " + method.getName() + "(");
Class[] paramTypes = method.getParameterTypes();
int length = 0;
for (int i = 0; i < paramTypes.length; i++) {
Class cla = paramTypes[i];
// System.out.print(" param:name-->" + cla.getName());
// System.out.print(" param:typeName-->" + cla.getTypeName());
length += 1;
System.out.print(cla.getSimpleName());
if (length != paramTypes.length) {
System.out.print(",");
}
}
System.out.println(")");
// 进行方法调用
// 设置方法的参数值
Object[] parameterValues = new Object[paramTypes.length];
for (int i = 0; i < paramTypes.length; i++) {
Class cla = paramTypes[i];
if (cla.getSimpleName().equals("int") || cla.getSimpleName().equals("Integer")) {
parameterValues[i] = 123;
}
if (cla.getSimpleName().equals("String")) {
parameterValues[i] = "testing";
}
if (cla.getSimpleName().equals("Double") || cla.getSimpleName().equals("double")) {
parameterValues[i] = 34.5;
}
if (cla.getSimpleName().equals("Long") || cla.getSimpleName().equals("long")) {
parameterValues[i] = 234l;
}
if (cla.getSimpleName().equals("Float") || cla.getSimpleName().equals("float")) {
parameterValues[i] = 234f;
}
if (cla.getSimpleName().equals("Boolean") || cla.getSimpleName().equals("boolean")) {
parameterValues[i] = true;
}
if (cla.getSimpleName().equals("Byte") || cla.getSimpleName().equals("byte")) {
parameterValues[i] = 3;
}
if (cla.getSimpleName().equals("char") || cla.getSimpleName().equals("Char")) {
parameterValues[i] = "c";
}
if (cla.getSimpleName().equals("Short") || cla.getSimpleName().equals("short")) {
parameterValues[i] = 5;
}
}
Object result = method.invoke(object, parameterValues);
System.out.println(result);
}
}
- 运行结果
boolean equals(Object)
false
class java.lang.String toString()
Person(name=null, age=0, address=null, salary=null, long1=0, aDouble=0.0, aDouble1=null, integer=null, aFloat1=null, aFloat=0.0, aBoolean=false, aBoolean1=null)
int hashCode()
-1186137629
class java.lang.String getAddress()
null
class java.lang.String getName()
null
void setName(String)
null
void function()
function
null
class java.lang.Integer getInteger()
null
void setAddress(String)
null
class java.lang.String getString(String,int)
testing---123
void method(String)
method testing
null
class java.lang.Long getSalary()
null
void setADouble1(Double)
null
void setLong1(long)
null
double getADouble()
0.0
void show()
show
null
void setAge(int)
null
int getAge()
123
long getLong1()
234
float getAFloat()
0.0
class java.lang.Float getAFloat1()
null
class java.lang.Boolean getABoolean1()
null
void setADouble(double)
null
void setInteger(Integer)
null
class java.lang.Double getADouble1()
34.5
void setAFloat1(Float)
null
void setAFloat(float)
null
void setSalary(Long)
null
void setABoolean(boolean)
null
boolean isABoolean()
true
void setABoolean1(Boolean)
null
boolean canEqual(Object)
false
4、查看测试类Person的属性并赋值
@Test
public void testFeild() throws Exception {
Class clazz = Class.forName("org.druiddemo.Person");
Object object = clazz.newInstance();// 构造无参对象
Field[] fs = clazz.getDeclaredFields();
for (int i = 0; i < fs.length; i++) {
Field field = fs[i];
field.setAccessible(true);
// 获取所有的属性名称及类型
// System.out.println(field.getType() + " " + field.getName() + " getValue:" + field.get(object));
// 针对属性名称进行赋值
if (field.getType() == Integer.class || field.getType() == int.class) {
field.set(object, 123);// set方法
System.out.println(field.getType() + " " + field.getName() + " getValue:" + field.get(object));
}
if (field.getType() == Long.class || field.getType() == long.class) {
field.set(object, 432l);
System.out.println(field.getType() + " " + field.getName() + " getValue:" + field.get(object));
}
if (field.getType() == Float.class || field.getType() == float.class) {
field.set(object, 431002f);
System.out.println(field.getType() + " " + field.getName() + " getValue:" + field.get(object));
}
if (field.getType() == Double.class || field.getType() == double.class) {
field.set(object, 434.554);
System.out.println(field.getType() + " " + field.getName() + " getValue:" + field.get(object));
}
if (field.getType() == String.class) {
field.set(object, "sting testing");
System.out.println(field.getType() + " " + field.getName() + " getValue:" + field.get(object));
}
if (field.getType() == char.class) {
// field.set(object,"c");
System.out.println(field.getType() + " " + field.getName() + " getValue:" + field.get(object));
}
if (field.getType() == byte.class || field.getType() == Byte.class) {
// field.set(object,2);
System.out.println(field.getType() + " " + field.getName() + " getValue:" + field.get(object));
}
if (field.getType() == short.class) {
// field.set(object,9);
System.out.println(field.getType() + " " + field.getName() + " getValue:" + field.get(object));
}
}
}
- 运行结果
class java.lang.String name getValue:sting testing
int age getValue:123
class java.lang.String address getValue:sting testing
class java.lang.Long salary getValue:432
long long1 getValue:432
double aDouble getValue:434.554
class java.lang.Double aDouble1 getValue:434.554
class java.lang.Integer integer getValue:123
class java.lang.Float aFloat1 getValue:431002.0
float aFloat getValue:431002.0
short aShort getValue:0
byte aByte getValue:0
class java.lang.Byte aByte1 getValue:null
char aChar getValue:
5、完整源码
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.junit.Test;
/**
* @author alanchan
*
*/
public class ReflectDemo {
@Test
public void testgetClass() throws ClassNotFoundException {
// 方式1
Person p = new Person();
Class c = p.getClass();
Person p2 = new Person();
Class c2 = p2.getClass();
System.out.println(p == p2);// false
System.out.println(c == c2);// true
// 方式2
Class c3 = Person.class;
// int.class;
// String.class;
System.out.println(c == c3);
// 方式3
// ClassNotFoundException
Class c4 = Class.forName("org.druiddemo.Person");
System.out.println(c == c4);
System.out.println(c + " " + c4);
}
@Test
public void testConstructor() throws Exception {
Class clazz = Class.forName("org.druiddemo.Person");
// 获取构造函数
// 1、获取public构造函数
System.out.println("1、获取public构造函数,如下:");
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor.getName());
}
System.out.println("2、获取所有构造函数,如下:");
// 2、获取所有构造函数
Constructor[] constructors1 = clazz.getDeclaredConstructors();
for (Constructor constructor : constructors1) {
System.out.println("2.1获取所有构造函数的参数类型,构造函数如下:");
System.out.print(constructor.getName() + " (");
// 2.1获取所有构造函数的参数类型
Class[] parameterTypes = constructor.getParameterTypes();
int typeleng = 0;
for (Class cla : parameterTypes) {
typeleng += 1;
System.out.print(cla.getName());
if (typeleng != parameterTypes.length) {
System.out.print(",");
}
}
System.out.println(") ");
}
// 根据构造函数的类型创建实例
System.out.println("3、根据构造函数的类型创建实例,如下:");
Constructor[] constructors2 = clazz.getDeclaredConstructors();
for (Constructor constructor : constructors2) {
System.out.println("3、根据构造函数的类型创建实例,构造函数如下:");
System.out.print(constructor.getName() + ":");
// 3、根据构造函数的类型创建实例
Class[] parameterTypes = constructor.getParameterTypes();
Object object = null;
constructor.setAccessible(true);
// 3.1创建无参构造函数
if (parameterTypes.length == 0) {
object = clazz.newInstance();
System.out.println("无参构造函数的toString:" + object.toString());
} else {
// 3.2有参构造函数,根据参数的类型进行构造
// 设置构造函数的参数值
Object[] parameterValues = new Object[parameterTypes.length];
for (int i = 0; i < parameterTypes.length; i++) {
Class cla = parameterTypes[i];
if (cla.getSimpleName().equals("int") || cla.getSimpleName().equals("Integer")) {
parameterValues[i] = 123;
}
if (cla.getSimpleName().equals("String")) {
parameterValues[i] = "testing";
}
if (cla.getSimpleName().equals("Double") || cla.getSimpleName().equals("double")) {
parameterValues[i] = 34.5;
}
if (cla.getSimpleName().equals("Long") || cla.getSimpleName().equals("long")) {
parameterValues[i] = 234l;
}
if (cla.getSimpleName().equals("Float") || cla.getSimpleName().equals("float")) {
parameterValues[i] = 234f;
}
if (cla.getSimpleName().equals("Boolean") || cla.getSimpleName().equals("boolean")) {
parameterValues[i] = true;
}
if (cla.getSimpleName().equals("Byte") || cla.getSimpleName().equals("byte")) {
parameterValues[i] = 3;
}
if (cla.getSimpleName().equals("char") || cla.getSimpleName().equals("Char")) {
parameterValues[i] = "c";
}
if (cla.getSimpleName().equals("Short") || cla.getSimpleName().equals("short")) {
parameterValues[i] = 5;
}
}
object = constructor.newInstance(parameterValues);
System.out.println("有参构造函数的toString:" + object);
}
// 3.2有参构造函数,根据参数的类型进行构造
for (Class cla : parameterTypes) {
System.out.print(" param:name-->" + cla.getName());
System.out.print(" param:typeName-->" + cla.getTypeName());
System.out.print(" param:simpleName-->" + cla.getSimpleName());
System.out.println(" param:modifiers-->" + cla.getModifiers());
}
}
}
@Test
public void testMethod() throws Exception {
Class clazz = Class.forName("org.druiddemo.Person");
Object object = clazz.newInstance();// 构造无参对象
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
method.setAccessible(true);
// 获取所有的方法名称、参数类型及返回数据类型
System.out.print(method.getReturnType() + " " + method.getName() + "(");
Class[] paramTypes = method.getParameterTypes();
int length = 0;
for (int i = 0; i < paramTypes.length; i++) {
Class cla = paramTypes[i];
// System.out.print(" param:name-->" + cla.getName());
// System.out.print(" param:typeName-->" + cla.getTypeName());
length += 1;
System.out.print(cla.getSimpleName());
if (length != paramTypes.length) {
System.out.print(",");
}
}
System.out.println(")");
// 进行方法调用
// 设置方法的参数值
Object[] parameterValues = new Object[paramTypes.length];
for (int i = 0; i < paramTypes.length; i++) {
Class cla = paramTypes[i];
if (cla.getSimpleName().equals("int") || cla.getSimpleName().equals("Integer")) {
parameterValues[i] = 123;
}
if (cla.getSimpleName().equals("String")) {
parameterValues[i] = "testing";
}
if (cla.getSimpleName().equals("Double") || cla.getSimpleName().equals("double")) {
parameterValues[i] = 34.5;
}
if (cla.getSimpleName().equals("Long") || cla.getSimpleName().equals("long")) {
parameterValues[i] = 234l;
}
if (cla.getSimpleName().equals("Float") || cla.getSimpleName().equals("float")) {
parameterValues[i] = 234f;
}
if (cla.getSimpleName().equals("Boolean") || cla.getSimpleName().equals("boolean")) {
parameterValues[i] = true;
}
if (cla.getSimpleName().equals("Byte") || cla.getSimpleName().equals("byte")) {
parameterValues[i] = 3;
}
if (cla.getSimpleName().equals("char") || cla.getSimpleName().equals("Char")) {
parameterValues[i] = "c";
}
if (cla.getSimpleName().equals("Short") || cla.getSimpleName().equals("short")) {
parameterValues[i] = 5;
}
}
Object result = method.invoke(object, parameterValues);
System.out.println(result);
}
}
@Test
public void testFeild() throws Exception {
Class clazz = Class.forName("org.druiddemo.Person");
Object object = clazz.newInstance();// 构造无参对象
Field[] fs = clazz.getDeclaredFields();
for (int i = 0; i < fs.length; i++) {
Field field = fs[i];
field.setAccessible(true);
// 获取所有的属性名称及类型
// System.out.println(field.getType() + " " + field.getName() + " getValue:" + field.get(object));
// 针对属性名称进行赋值
if (field.getType() == Integer.class || field.getType() == int.class) {
field.set(object, 123);// set方法
System.out.println(field.getType() + " " + field.getName() + " getValue:" + field.get(object));
}
if (field.getType() == Long.class || field.getType() == long.class) {
field.set(object, 432l);
System.out.println(field.getType() + " " + field.getName() + " getValue:" + field.get(object));
}
if (field.getType() == Float.class || field.getType() == float.class) {
field.set(object, 431002f);
System.out.println(field.getType() + " " + field.getName() + " getValue:" + field.get(object));
}
if (field.getType() == Double.class || field.getType() == double.class) {
field.set(object, 434.554);
System.out.println(field.getType() + " " + field.getName() + " getValue:" + field.get(object));
}
if (field.getType() == String.class) {
field.set(object, "sting testing");
System.out.println(field.getType() + " " + field.getName() + " getValue:" + field.get(object));
}
if (field.getType() == char.class) {
// field.set(object,"c");
System.out.println(field.getType() + " " + field.getName() + " getValue:" + field.get(object));
}
if (field.getType() == byte.class || field.getType() == Byte.class) {
// field.set(object,2);
System.out.println(field.getType() + " " + field.getName() + " getValue:" + field.get(object));
}
if (field.getType() == short.class) {
// field.set(object,9);
System.out.println(field.getType() + " " + field.getName() + " getValue:" + field.get(object));
}
}
}
}
以上 ,介绍了java反射内容、类如何加载以及反射的具体应用。