java反射实际应用_Java反射知识的应用

1、反射的概念

反射是java语言的一个特性,它允程序在运行时(注意不是编译时期)来进行自我检查并且对内部的成员进行操作。例如它允许一个java的类获取他所有的成员变量和方法并且显示出来。一个常见的例子是在JavaBean中,一些组件可以通过一个构造器来操作。这个构造器就是用的反射在动态加载的时候来获取的java中类的属性的。

2、反射相关的核心类

public classUser {privateString name;private intage;publicUser(){super();

}public User(String name, intage) {super();this.name =name;this.age =age;

}publicString sayHello(String name){return "Hello,"+name;

}//get set...

}

2.1、Class

java中获取对象字节码的方式

@Testpublic void classTest() throwsException{

User user= newUser();

String className= "org.javacode.model.User";

Class> clazz1 =Class.forName(className);

Class> clazz2 = User.class;

Class> clazz3 =user.getClass();

System.out.println(clazz1==clazz2);

System.out.println(clazz2==clazz3);

}

输出结果都为true,可见同一个类中只有唯一一份字节码。获取Class对象有3种方式。

2.2、Constructor 构造器

@Testpublic void constructor() throwsException{//通过constructor构造对象

Class clazz = User.class;

Constructor constructor = clazz.getConstructor(String.class,int.class);

User user= constructor.newInstance("zhangsan",26);

String name=user.getName();

System.out.println(name);

}

通过Constructor构造对象,除此之外还有的方法:

getConstructors()获取所有的构造器;

getDeclaredConstructor(Class>... parameterTypes) 获取声明给定参数的构造器

getDeclaredConstructors() 获取所有声明的构造器

newInstance(Object... initargs)  使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。

...

2.3、Method 方法

@Testpublic void method() throwsException{

Class clazz = User.class;

Method method= clazz.getDeclaredMethod("sayHello", String.class);

Object obj=clazz.newInstance();

Object resultObj= method.invoke(obj, "Hehe");

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

}

通过class获取Method,其中比较核心的方法是method.invoke(Object , parameters...); 也就是通过Method调用对象的某一个方法,参数是动态的,这主要是为了区别方法的重载(Overloading) 。

2.4、Field 属性

@Testpublic void field() throwsException{

Class clazz = User.class;

Field[] fields=clazz.getDeclaredFields() ;for(Field field : fields) {

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

}

}

通过getDeclaredFields() 可以获取对象中所有的属性。在Constructor,Method,Field中都有getXXX和getDeclaredXXX的方法,他们的区别主要是访问权限的问题,getXXX 是不能获取private的属性,构造器以及方法的。

3、反射和工厂模式的结合

public interfaceBaseCache {public voidput(String key,Object value);

}public class LocalCache implementsBaseCache{public voidput(String key, Object value) {

System.out.println("local...");

}

}public class RedisCache implementsBaseCache {public voidput(String key, Object value) {

System.out.println("redis...");

}

}

public classCacheFactory {public staticBaseCache getInstance(String className) {try{

Class> clazz =Class.forName(className);

BaseCache cache=(BaseCache) clazz.newInstance();returncache;

}catch (ClassNotFoundException |InstantiationException|IllegalAccessException e) {

e.printStackTrace();return null;

}

}

}

通过指定类名我们可以通过反射到具体的实现类,最起码在这里是可以减少好几个if else 的,那么的更好一点做法可以将className写到配置文件中,当需要不同的实现类时,只要改配置文件即可,而不用修改代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值