一、什么是Java反射
Java反射是Java语言自身提供的一种运行机制,主要作用是实现类的动态加载,增加程序的灵活性,实现程序的进一步解耦,举个例子
class Office
{
public static void main(String[] args)
{
//new 创建对象是静态加载类,在编译时刻就需要加载所有可能使用到的类
//通过动态加载类可以解决该问题
if("Word".equals(args[0]))
{
Word w = new Word();
w.start();
}
if("Excel".equals(args[0])){
Excel e = new Excel();
e.start();
}
}
}
运行结果:
出现这类错误的是因为通过new关键字创建的对象是静态加载的,意思就是在编译阶段就会被创建,可是现在还不存在Word类和Excel类,所以无法通过编译
解决方法是变动态加载为静态加载,即使用Java反射机制,具体实现如下:
先说一句帮助大家理解的话:在Java中万事万物皆对象,那么我们自己写的类也是对象,是Java中Class类的对象
class Office
{
public static void main(String[] args)
{
if("Word".equals(args[0]))
{
try{
//调用Class类的forName方法,根据类名获取反射
Class c1 = Class.forName("Word");
//调用Class类的newInstance方法创建对象
Word w =(Word) c1.newInstance();
}catch(Exception e){
e.printStackTrace();
}
//Word w = new Word();
//w.start();
}
if("Excel".equals(args[0])){
//Excel e = new Excel();
//e.start();
}
}
}
运行结果:
这样程序编译的时候就不会报错了,因为现在的对象是在运行阶段创建的,只有当你用到某个类的实例对象时该对象才会被创建。
那么如何实现程序的的进一步解耦呢,同样举例说明:
首先,我们需要创建一个接口类来制定一个人统一的标准
interface OfficeAble
{
public void start();
}
然后让Word类和Excel类来实现这个接口
Word类:
class Word implements OfficeAble
{
public void start()
{
System.out.println("word starts");
}
}
Excel类:
class Excel implements OfficeAble
{
public void start()
{
System.out.println("excel starts");
}
}
然后是修改后的Office类:
class OfficeBetter
{
public static void main(String[] args)
{
try{
//根据传入的参数创建该参数的反射(官网称为类类型)
Class c1 = Class.forName(args[0]);
//上转型,创建传入参数类的实例对象
OfficeAble oa =(OfficeAble)c1.newInstance();
oa.start();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
运行结果:
通过将类型参数化就实现了等号右边的解耦,可以根据需要调用的类的不同创建不同类的实例化对象,这样以后不管你其他的类怎么改动都不需要再改动此处代码。