Java反射中Class对象获取方式

1. 什么是反射

反射:就是对象的反向处理
那么正的的操作是什么?当我们实例化一个对象,首先要创建一个类,new一个它的构造方法,就能实例化一个对象。它的处理流程就是:包名.类名;通过包名,在找到类名。
反射中的“反”:就是根据对象来取得对象的来源信息。而这个反的的操作核心取决于Object的一个方法。取得Class对象。

public final native Class<?> getClass();

该方法返回的是一个Class类对象,这个Class描述的就是类
在反射的世界里,看中的不在是一个对象,而是对象身后的组成类(类,构造,普通,成员)。

2. Class类对象的三种获取方式

对类型(类)的一个抽象,就是JDK中的Class类,用来描述我们所定义的类。
Class的获取方式:

  1. 通过对象的getClass方法获取,比如:obj.getClass();
  2. 通过类名.class获取类的对象;
  3. 通过Class类的静态方法forName(String className) 获取Class对象,要捕获异常。

在以上三个方法中,我们可以看出,除了第一种方法会产生类的实例化对象外,其他的两种都不会产生类的实例化对象。所以在取得了Class类对象的一个最直接的好处:可以通过反射实例化对象。
举例:三种获取Class对象信息的方式


public class TestReflect {
    public static void main(String[] args) {
        //1.第一种方式
        //通过类名,调用构造方法,创建对象
        Date date = new Date();
        //通过date对象来获取创建date的类型,赋给Class对象
        Class classz = date.getClass();

        System.out.println(classz);   //class java.util.Date
        System.out.println(classz.getName());  //java.util.Date

        //第二种方式
        //不需要实例化对象,   类名.class
        Class classz1 = Date.class;
        System.out.println(classz1 == classz);  //true

        //第三种方式
        //使用Class的静态方法,其中forName中的类名称是所在的包名加类名
        try {
            Class classz2 = Class.forName("java.util.Date");
            System.out.println(classz2 == classz1);  //true
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }
}

那么怎样通过反射实例化对象,Class中提供了一个方法。如下:

public T newInstance()
        throws InstantiationException, IllegalAccessException

即当我们获取对象类的信息,在通过Class对象调用newInstance()方法(相当于new了一个对象),就实例化了一个对象。
举例:通过反射实例化对象


public class TestReflect {
    public static void main(String[] args) {
        //第二种方式
        Class classz = Date.class;
        try {
            //此处就等价于new java.util.Date
            Object object = classz.newInstance();
            System.out.println(object);
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        System.out.println();

        //第三种方式
        try {
            Class classz1 = Class.forName("java.util.Date");
            Object object = classz1.newInstance();
            System.out.println(object);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }
}

现在我们发现实例化对象的第二种方式:通过反射实现
取得Class对象就意味着取得了类的指定操作权。

3. 反射的应用

简单工厂模式的应用

对于传统工厂(简单工厂)来说,当增加一个新的产品类,将修改工厂方法中的代码,这违背了开闭原则
举例如下:


interface Fruit{
    void eat();
}

class Apple implements Fruit{
    @Override
    public void eat() {
        System.out.println("吃苹果");
    }
}

class FruitFactory{
    public static Fruit getFruitInstance(String fruitName){
        if(fruitName.equals("Apple")){
            return new Apple();
        }
        return null;
    }
}
public class TestFactory {
    public static void main(String[] args) {
        Fruit fruit = FruitFactory.getFruitInstance("Apple");
        fruit.eat();
    }

}

如果此时想要加一个产品类橘子,那么就要修改工厂类中的代码。那么可以通过反射来解决,因为反射可以通过Class对象来newInstance()实例化一个对象
举例:使用反射之后的简单工厂方法


interface Fruit{
    void eat();
}

class Apple implements Fruit{
    @Override
    public void eat() {
        System.out.println("吃苹果");
    }
}

class FruitFactory{
    public static Fruit getFruitInstance(String className){
        try {
            Class classz = Class.forName(className);
            return (Fruit) classz.newInstance();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return null;
    }
}
public class TestFactory {
    public static void main(String[] args) {
        Fruit fruit = FruitFactory.getFruitInstance("www.csdn.classse.Apple");
        fruit.eat();
    }

}

简单工厂结合反射来使用,能够减少功能扩展带来的修改问题,在增加新的接口子类时,可以很方便的进行接口子类扩展

猜你喜欢

转载自blog.csdn.net/mi_zhi_lu/article/details/91450670