【Java】Java反射笔记
反射的作用
- 在运行时获取类的信息。如果没有反射,则需要由new创建对象,在代码里写死了,若需要使用不同的类型,就需要修改代码来,执行不同的操作。
例子1:如果有一个简单的工厂模式:
interface Inter{
void doSomething();
}
class AA implements Inter{
@Override
public void doSomething() {
System.out.println("AA do something");
}
}
class BB implements Inter{
@Override
public void doSomething() {
System.out.println("BB do something");
}
}
//简答工厂模式,获得实例化对象
class Factory{
public static Inter getInstance(String className){
Inter inter = null;
if(className.equals("AA")){
inter = new AA();
}else if(className.equals("BB")){
inter = new BB();
}
return inter;
}
}
class Test{
public static void main(String[] args) {
Inter inter = Factory.getInstance("BB");
inter.doSomething();
}
}
在没有反射机制时,若有其他类实现了Inter接口,若要通过工厂获取该类的实例,则必须修改Factory类,不方便。
现在利用反射机制实现工厂类:
class Factory{
public static Inter getInstance(String className){
Inter inter = null;
try {
Class ca = Class.forName(className);
inter = (Inter) ca.newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
return inter;
}
}
class Test{
public static void main(String[] args) {
Inter inter = Factory.getInstance("基础.BB");
inter.doSomething();
}
}
现在无论有多少个类实现了Inter接口,我们都不需要修改工厂类。大大简化了编码。
例子2:动态代理
动态代理是用一个中间类,在不修改原有代码的基础上,做一些额外的动作,例如扩展功能或者同一接口等。
可参考:https://blog.csdn.net/wxgxgp/article/details/79834853
什么是反射?
官方的话就是:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
通俗的说就是可以不用在运行之前就确定是哪一个类,而是在运行的时候再去确定。也就是代码执行到了需要某个类的实例化对象的时候,再去找那个类的Class对象,从Class对象里获取到这个类的信息,并对它进行操作。
这里Class就是反射的基础,所有的类(包括基本数据类型和void)都有.class来获取这个Class对象。通常有3重方式获取class对象:
① 类.class;
② Class.forName(类的全限定名);
③ 对象.getClass();
例如一般通过AA aa = new AA();
来床架一个对象。
利用反射则可以这样来创建对象(还是利用上边第一个例子里的类和接口):
Class ca = Class.forName("AA");//获取AA类的class对象
(Inter)ca.newInstance();//获取aa的一个实例
以上两句话就相当于AA aa = new AA();
这样写比直接new的好处在哪呢?
好处就是只要是实现了Inter这个接口的类,只要传入类名,就可以调用不同的子类实现。
还可以这样改:
String className = getClassNameFromXml;
Class ca = Class.forName(className);//获取AA类的class对象
(Inter)ca.newInstance();//获取aa的一个实例
这样可以从xml文件读取类信息,上边的代码完全可以不用修改,有很好的扩展性。