首页 > 代码库 > java中的反射机制

java中的反射机制

1、反射 && Class类

假设有一个Test类定义如下:

class Test
{
	public void testFunction()
	{
		System.out.println("you are here...");
	}

}

这时,我们需要一个实例化的Test类型的对象,通常的做法是:

Test test1 = new Test();

通常这种做法是足够的,但在某些特定的场景下,new很可能并不是最理想的实例化对象方式(见后文)

而反射机制,往往能弥补new在这些场景下的不足。


而反射的实现离不开一个重要的类:Class类。

Class类可以简单理解为:“类的类”,至于具体是什么类呢,这是需要程序在运行时推导的,因此Class类的泛型用 ? 表示一个未知的类。

Class<?>


下面有三种得到指定类的Class<?>类型对象的方式:

//方式1:通过Object类的getClass()方法取得(通常很少用这种方式)
		Test test_1 = new Test();
		Class<?> cls_1 = test_1.getClass();
		System.out.println(cls_1.getName());


//方式2:使用“类.class”取得
		Class<?> cls_2 = Test.class;
		System.out.println(cls_2.getName());


//方式3:使用Class中的forName方法 (常用方式)
        Class<?> cls_3 = Class.forName("com.test.mine.Test");
		System.out.println(cls_3.getName());

有了这个 Class<?>的对象,就可以调用其内部的 newInstance()方法,得到一个要求的对象了

接下来,实例化目标对象:

        Test obj = (Test)cls_3.newInstance();  //这个函数的返回值类型是Object


2、应用场景

有这样一种场景:比如在工厂模式下,我们有可能需要经常增删工厂生产的产品,在这样的场景下,如果用new去实现工厂的生产方法,由于new必须调用指定类的构造方法的特性会让程序的整体结构非常死板。

package com.test.mine;

/////传统的

interface Fruit {
public void eat() ;
}

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

class Orange implements Fruit {
public void eat() {
	System.out.println("吃橘子。");
}
}

/////////////////////
public class ClassFactory {
	public static Fruit getInstance(String className) {
		if("apple".equals(className)){
			return new Apple() ;
		}
		if("orange".equals(className)){
			return new Orange();
		}
		
		//////.......
		return null;
	}
	
	public static void main(String[] args) {
		Fruit apple = ClassFactory.getInstance("apple");
		apple.eat();
		Fruit orange = ClassFactory.getInstance("orange");
		orange.eat();
	}
}

举个例子:一旦生产的产品发生了改变,违背“低耦合”特性的传统的工厂模式需要手动修改工厂的生产方法,而如果能让工厂的生产方法去动态的推导生产什么产品,并生产对应的产品,那么系统的耦合性就会提高许多。

具体的实现如下:

package com.test.mine;

interface NewFruit {
public void eat() ;
}

class NewApple implements NewFruit {
public void eat() {
	System.out.println("吃苹果。");
}
}

class NewOrange implements NewFruit {
public void eat() {
	System.out.println("吃橘子。");
}
}


public class NewFactory {
	public static NewFruit getInstance(String className){
		NewFruit ret = null;
		try {
			ret = (NewFruit)Class.forName(className).newInstance();
		} catch (Exception e) {
			// TODO: handle exception
		}
		return ret;
	}
	//////
	public static void main(String[] args) {
		NewFruit apple = NewFactory.getInstance("com.test.mine.NewApple");
		apple.eat();
		NewFruit orange = NewFactory.getInstance("com.test.mine.NewOrange");
		orange.eat();
	}
}

//有关工厂模式,之后会写一篇文章,单独介绍


3、反射方法

//反射方法
		Class<?> cls_4 = Class.forName("com.test.mine.Test");
		Method m1 = cls_4.getDeclaredMethod("testFunction");
		Object obj = cls_4.newInstance();
		m1.invoke(obj);


java中的反射机制