Java中反射主要应用在哪里_Java学习:反射的应用场景和解析方法

提到java语言的高级特性,反射绝对是Top1级别的,在大量开源框架中的应用范例比比皆是,那么需要了解清楚反射到底是什么?为什么要使用反射?如何使用反射?(what,why,how)

什么是反射?

正常场景下,java从源码到运行有3个阶段:

source class runtime

反射提供的是runtime阶段获取类的class实例、方法、属性、注解,并且能够调用类的方法的途径,这种动态获取类信息和调用类方法的机制被称之为反射

为什么要使用反射?

正常的实例化一个对象

ClassA objA = new ClassA();

objA.sayHello();

通过反射去实例化一个对象

Class objA = ClassA.class;

Method method = objA.getMethod("sayHello");

method.invoke(objA.newInstance());

在source阶段实际上二者并无任何区别,反射也没有体现出任何的优势,那么任何一个java开发人员必然会问为什么要使用反射?

反射的重点在于runtime阶段的获取类信息和调用类方法,那么当你的编码过程中中有“部分信息是source阶段不清晰,需要在runtime阶段动态临时加载”这种场景,反射就可以派上用场了

我们考虑几个编码场景:

1、编码阶段不知道需要实例化的类名是哪个,需要在runtime从配置文件中加载:

Class clazz = class.forName("xxx.xxx.xxx")

clazz.newInstance();

2、在runtime阶段,需要临时访问类的某个私有属性

ClassA objA = new ClassA();

Field xxx = objA.getClass().getDeclaredField("xxx")

xxx.setAccessible(true);

所以,反射的优点在于“有些编码需求在source阶段无法实现,只能在runtime阶段通过反射实现”,而非“source阶段正常编码方式能解决的,反射的方式能解决的更好”,所以比较反射和正常编码方式的优劣是没有意义的,反射解决的是正常编码无法解决的编码场景,如果正常编码方式可以解决的,强行使用反射反而是毫无意义的,编码不是为了show技巧。

反射应用范例代码

实现对类或者对象的构造器、方法、属性、注解的获取和操作,具体作用见代码中的注释描述

public class ReflectionHelper {

/**

* Reflection Test Code

*

* @param args

*/

public static void main(String[] args) {

SSHClient sshClient = new SSHClient();

// 获取class名称

System.out.println("01-----获取class名称-----");

System.out.println(sshClient.getClass().getName());

System.out.println(sshClient.getClass().getSimpleName());

System.out.println(sshClient.getClass().getTypeName());

Class> clazz1 = null;

Class> clazz2 = null;

Class> clazz3 = null;

// 获取对象或者类的Class实例

try {

clazz1 = Class.forName(sshClient.getClass().getName());

clazz2 = sshClient.getClass();

clazz3 = ReflectionUtils.class;

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

// 获取类的构造函数,用构造函数实例一个对象

for (Constructor> clazz1Cstor : clazz1.getConstructors()) {

System.out.println(clazz1Cstor.getName());

try {

SSHClient client1 = (SSHClient) clazz1.newInstance();

SSHClient client2 = (SSHClient) clazz1Cstor.newInstance();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (InvocationTargetException e) {

e.printStackTrace();

}

}

// 获取类定义的方法、属性

System.out.println("02-----获取类定义的方法、属性-----");

try {

SSHClient client = (SSHClient) clazz1.newInstance();

Method setHostMethod = clazz1.getDeclaredMethod("setHost", String.class);

setHostMethod.invoke(client, "111");

Field field = client.getClass().getDeclaredField("host");

field.setAccessible(true);

System.out.println(field.get(client));

field.set(client,"a new host");

System.out.println(field.get(client));

} catch (NoSuchMethodException e) {

e.printStackTrace();

} catch (IllegalAccessException e) {

e.printStackTrace();

} catch (InstantiationException e) {

e.printStackTrace();

} catch (InvocationTargetException e) {

e.printStackTrace();

} catch (NoSuchFieldException e) {

e.printStackTrace();

}

// 获取类的注解

System.out.println("03-----获取类使用的注解-----");

for (Annotation annotation : clazz1.getAnnotations()) {

System.out.println(annotation.getClass().getName());

System.out.println(annotation.toString());

System.out.println(annotation.annotationType());

}

}

}

运行结果:

你可能感兴趣的:(Java中反射主要应用在哪里)