Java 反射机制详解

原创
05/21 17:20
阅读数 67

Java 反射机制

Java反射机制的概念

由Java的类实例化对象,叫做“正”,那么由一个对象,反推出对象的类叫做“反射”

Class 类对象的三种实例化模式

反射中的操作都是通过Class类展开的,Class类是反射操作的根源所在。可以由三种实例化方式java.lang.Class类

  • Object类可以通过 getClass(),Class类的getName()方法,可以获得类的完整名称。使用这种方式,必须实例化对象。
public static void main(String[] args) {
		Person person = new Person();
		Class<?> clsClass = person.getClass();
		System.out.println(clsClass);
		System.out.println(clsClass.getName());
}
  • JVM直接支持采用“类.class”的形式实例化。使用这种方式,必须导入类所在的包。
	public static void main(String[] args) {
		Class<?> cls = Person.class;
		System.out.println(cls.getName());
}
  • Class类支持。Class类中有一个静态方法,forName(String className)
Class<?> c = Class.forName("com.xx.Person");

反射实例化对象

获取Class对象之后的最大意义实际上并不是在于只是一个对象的实例化操作形式,更重要的是Class类里面提供有一个对象的反射实例化方法,newInstance() (jdk1.9以前),1.9以后用 getDeclaredConstructor().newInstance()。通过反射实现的实例化处理,依然会调用类的无参构造函数。

反射与工厂模式

传统的工厂模式,需要在工厂类的内部判断需要创建的对象的类型。这种情况下每次增加一个类,都需要修改工厂类。所以,为了让工厂类能够服务所有的类,必须使用到反射,给工厂类一个字符传,工厂类通过字符串创建对象返回出去。

package com.test;

/**
 * Factory
 */
class Factory {
    @SuppressWarnings("unchecked")
    public static <T> T getInstance(String className, Class<T> clazz) {
        T instance = null;

        try {
            instance = (T) Class.forName(className).newInstance();
        } catch (Exception e) {
            e.printStackTrace();
        } 
        return instance;
    }
}

interface IMessage {
    public void send() ;
}
class Message implements IMessage {
    @Override
    public void send() {
        System.out.println("Message");
    }
}
public class App 
{
    public static void main( String[] args )
    {
        IMessage msg = Factory.getInstance("com.test.Message", IMessage.class);
        msg.send();
    }
}

此时用反射,就是为了解耦

反射与单例模式

单例模式,对于此文的实现四,下面的实现更好

public class Singleton {

    // 使用volatile关键字
    private static volatile Singleton instance;
    
    // 构造方法私有化
    private Singleton() {}
    
    // 静态方法返回该实例
    public static Singleton getInstance() {
        // 第一次检查instance是否被实例化出来,如果没有进入if块
        if(instance == null) {
            synchronized (Singleton.class) {
                // 某个线程取得了类锁,实例化对象前第二次检查instance是否已经被实例化出来,如果没有,才最终实例出对象
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}
// 饿汉式单例
class Singleton {
	private static final Singleton INSTANCE = new Singleton();
	private Singleton() {
		System.out.println("singleton init");
	}
	public static Singleton getInstance() {
		return INSTANCE;
	}
}

反射获取类结构信息

  • 当获取了一个类的Class对象时,意味着可以获取这个对象的一切继承结构信息。
展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部