一、Java反射机制概述
Java放射机制是指在==运行状态==中,对于任意一个类,都能知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意一个方法和属性;这种动态获取信息及动态调用方法的功能成为Java的反射机制。
二、反射的作用
- 利用Java机制,在Java程序中可以动态的去调用一些protected甚至是private的方法或类,这样就可以在很大程度上满足一些特殊需求。
- 在Android SDK的源码中,很多类或方法中经常加上了“@hide”注释标记,它的作用是使这个方法或类在生成SDK时不可见,所以程序可能无法编译通过,而且在最终发布的时候,就可能存在一些问题。对于这种问题,第一种方法就是自己去掉源码中的“@hide”标记,然后在重新编译生成一个SDK。另一种方法就是使用Java反射机制,利用反射机制可以访问存在访问权限的方法或修改其访问域。
- 可能有人会有疑问,明明直接new对象就好了,为什么非要用反射呢?代码量不是反而增加了?其实反射的初衷不是方便你去创建一个对象,而是让你在写代码的时候可以更加灵活,降低耦合,提高代码的自适应能力。
怎么样降低耦合度,提高代码的自适应能力?
通过接口实现,但是接口如果需要用到new关键字,这时候耦合问题又会出现
举个例子:
/**
/**
* @ClassName: TestReflection
* @Model : (所属模块名称)
* @Description: 使用反射降低耦合度(通过接口来实现)
* @author Administrator
* @date 2017年6月2日 下午5:09:38
*/
public class TestReflection {
/**
/**
* main (这里用一句话描述这个方法的作用)
* @param args
* void
* @ModifiedPerson Administrator
* @date 2017年6月2日 下午5:09:38
*/
public static void main(String[] args) {
//普通写法,使用New 关键字
ITest iTest = createITest("ITestImpl1");
iTest.testReflect();
ITest iTest2 = createITest("ITestImpl2");
iTest2.testReflect();
}
/**
* createITest 普通写法,使用New关键字,但是假设有1000个不同ITest需要创建,那你打算写1000个 if语句来返回不同的ITest对象?
* @param name
* @return
* ITest
* @ModifiedPerson Administrator
* @date 2017年6月2日 下午5:32:21
*/
public static ITest createITest(String name){
if (name.equals("ITestImpl1")) {
return new ITestImpl1();
} else if(name.equals("ITestImpl2")){
return new ITestImpl2();
}
return null;
}
}
interface ITest{
public void testReflect();
}
class ITestImpl1 implements ITest{
/* (non-Javadoc)
* <p>Title: test</p>
* <p>Description: </p>
* @see ITest#test()
*/
@Override
public void testReflect() {
System.out.println("I am ITestImpl1 !");
}
}
class ITestImpl2 implements ITest{
/* (non-Javadoc)
* <p>Title: testReflect</p>
* <p>Description: </p>
* @see ITest#testReflect()
*/
@Override
public void testReflect() {
System.out.println("I am ITestImpl2 !");
}
}
假设有1000个不同ITest需要创建,那你打算写1000个 if语句来返回不同的ITest对象?
如果使用反射机制呢?
/**
/**
* @ClassName: TestReflection
* @Model : (所属模块名称)
* @Description: 使用反射降低耦合度(通过接口来实现)
* @author Administrator
* @date 2017年6月2日 下午5:09:38
*/
public class TestReflection {
/**
/**
* main (这里用一句话描述这个方法的作用)
* @param args
* void
* @ModifiedPerson Administrator
* @date 2017年6月2日 下午5:09:38
*/
public static void main(String[] args) {
//普通写法,使用New 关键字
ITest iTest = createITest("ITestImpl1");
iTest.testReflect();
ITest iTest2 = createITest("ITestImpl2");
iTest2.testReflect();
//使用反射机制
ITest iTest3 = createITest2("ITestImpl1");
iTest3.testReflect();
ITest iTest4 = createITest2("ITestImpl2");
iTest4.testReflect();
}
/**
* createITest 普通写法,使用New关键字,但是假设有1000个不同ITest需要创建,那你打算写1000个 if语句来返回不同的ITest对象?
* @param name
* @return
* ITest
* @ModifiedPerson Administrator
* @date 2017年6月2日 下午5:32:21
*/
public static ITest createITest(String name){
if (name.equals("ITestImpl1")) {
return new ITestImpl1();
} else if(name.equals("ITestImpl2")){
return new ITestImpl2();
}
return null;
}
/**
* createITest2 使用反射机制:当有1000个不同ITest需要创建时,不用针对每个创建ITest对象
* @param name
* @return
* ITest
* @ModifiedPerson Administrator
* @date 2017年6月2日 下午5:34:55
*/
public static ITest createITest2(String name){
try {
Class<?> class1 = Class.forName(name);
ITest iTest = (ITest) class1.newInstance();
return iTest;
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
interface ITest{
public void testReflect();
}
class ITestImpl1 implements ITest{
/* (non-Javadoc)
* <p>Title: test</p>
* <p>Description: </p>
* @see ITest#test()
*/
@Override
public void testReflect() {
System.out.println("I am ITestImpl1 !");
}
}
class ITestImpl2 implements ITest{
/* (non-Javadoc)
* <p>Title: testReflect</p>
* <p>Description: </p>
* @see ITest#testReflect()
*/
@Override
public void testReflect() {
System.out.println("I am ITestImpl2 !");
}
}
利用反射机制进行解耦的原理:就是利用反射机制"动态"的创建对象:向createITest()方法传入Hero类的包名.类名 通过加载指定的类,然后再实例化对象.