java反射机制 Java语言反射提供一种动态链接程序组件的多功能方法。它允许程序创建和控制任何类的对象(根据安全性限制),无需提前硬编码目标类。 这些特性使得反射特别适用于创建以非常普通的方式与对象协作的库。例如,反射经常在持续存储对象为数据库、XML或其它外部格式的框架中使用。
反射有两个缺点。第一个是性能问题。当用于字段和方法接入时反射要远慢于直接代码。性能问题的程度取决于程序中是如何使用反射的.
如果它作为程序运行中相对很少涉及的部分,缓慢的性能将不会是一个问题。即使测试中最坏情况下的计时图显示的反射操作只耗用几微秒。
仅反射在性能关键的应用的核心逻辑中使用时性能问题才变得至关重要。
许多应用更严重的一个缺点是使用反射会模糊程序内部实际要发生的事情。程序人员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术会带来维护问题。
反射代码比相应的直接代码更复杂,正如性能比较的代码实例中看到的一样。解决这些问题的最佳方案是保守地使用反射-- 仅在它可以真正增加灵活性的地方记录其在目标类中的使用.
/* *
* @author smart
*/
public class ReflectTest {
public ReflectTest(String value) {
System.out.println("declared value:"+value);
}
public ReflectTest(){ }
public static void main(String[] args) {
ReflectTest.classObject();
ReflectTest.clsssdeclaredObject();
ReflectTest.classMothodObject();
}
/**
* 直接创建对象调用方法 */
private static void classObject(){
try {
//参数值
Object []value=new Object[]{"1","2"};
//参数类型
Class par[]=new Class[]{String.class,String.class};
Class c=Class.forName("zjnx.sibas.ReflectTest");
//创建类对象
Object object=c.newInstance();
//得到方法对象
Method method=object.getClass().getDeclaredMethod("towStringEq", par);
//调用方法
boolean flag=Boolean.parseBoolean(method.invoke(object, value).toString());
System.out.println("flag:"+flag);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 调用有参构造函数,调用方法
*/
private static void clsssdeclaredObject(){
try {
//参数值
Object []value=new Object[]{new String[]{"1","2","3"},new Integer(1)};
//参数类型
Class par[]=new Class[]{String[].class,int.class};
//构造函数参数
Class declared[]=new Class[]{String.class};
//构造函数值
Object declaredValue[]=new Object[]{"1"};
Class c=Class.forName("zjnx.sibas.ReflectTest");
//初始化构造函数
Constructor constructor = c.getDeclaredConstructor(declared);
//新建对象
Object object=constructor.newInstance(declaredValue);
//得到方法对象
Method method=object.getClass().getDeclaredMethod("printValue", par);
//调用方法
method.invoke(object, value);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void classMothodObject(){
try {
//构造函数参数
//参数值
Object []value=new Object[]{new String[]{"1","2","3"},new Integer(1)};
//参数类型
Class par[]=new Class[]{String[].class,int.class};
//构造函数参数
Object declared[]=new Object[]{"1"};
//类完整路径
String className="zjnx.sibas.ReflectTest";
Object object=ReflectTest.getInstance(className, declared);
//Object object=ReflectTest.getInstance(className, null);
//得到方法对象
Method method=object.getClass().getDeclaredMethod("printValue", par);
//调用方法
method.invoke(object, value);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 按照指定的类名称 并按照指定的参数进行构造而获取实例
*
* 限制性条件为: objects 中的className 必须和构造参数中的类型一致。
*
* 如果Object 中存在 超越 参数类型的方法将导致初始化失败!!!! 例如 getInstance("Cr", {new
* Integer(2)}); 将无法应用在构造 方法 Cr(Number num)
* @param className 类名称
* @param objects 构造方法的类名称
* @return 返回构造出的实例
* @throws Exception 初始化错误时返回此项例外
*/
public static final Object getInstance(String className, Object[] objects) {
try {
Class clz = Class.forName(className);
if (objects==null ||objects.length==0)
{
return clz.newInstance() ;
}
Class[] paramClaszz = new Class[objects.length];
for (int i = 0; i < objects.length; i++) {
paramClaszz[i] = objects[i].getClass();
}
Constructor constructor = clz.getDeclaredConstructor(paramClaszz);
return constructor.newInstance(objects);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 是不是某个类的实例
* @param obj 实例
* @param cls 类
* @return 如果 obj 是此类的实例,则返回 true
*/
public boolean isInstance(Object obj, Class cls) {
return cls.isInstance(obj);
}
/**
* 得到某个对象的公共属性
* @param owner, fieldName
* @return 该属性对象
* @throws Exception
*/
public Object getProperty(Object owner, String fieldName) {
try {
Class ownerClass = owner.getClass();
Field field = ownerClass.getField(fieldName);
Object property = field.get(owner);
return property;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 得到某类的静态公共属性
* @param className 类名
* @param fieldName 属性名
* @return 该属性对象
* @throws Exception
*/
public Object getStaticProperty(String className, String fieldName){
try {
Class ownerClass = Class.forName(className);
Field field = ownerClass.getField(fieldName);
Object property = field.get(ownerClass);
return property;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private boolean towStringEq(String str1,String str2) {
System.out.println("str1:"+str1+" str2:"+str2);
if (str1.equals(str2)) {
return true;
}else{
return false;
}
}
private void printValue(String []arr,int i) {
System.out.println("i:"+i);
for (int j = 0; j < arr.length; j++) {
System.out.println("arr["+j+"]:"+arr[j]);
}
}
}
反射有两个缺点。第一个是性能问题。当用于字段和方法接入时反射要远慢于直接代码。性能问题的程度取决于程序中是如何使用反射的.
如果它作为程序运行中相对很少涉及的部分,缓慢的性能将不会是一个问题。即使测试中最坏情况下的计时图显示的反射操作只耗用几微秒。
仅反射在性能关键的应用的核心逻辑中使用时性能问题才变得至关重要。
许多应用更严重的一个缺点是使用反射会模糊程序内部实际要发生的事情。程序人员希望在源代码中看到程序的逻辑,反射等绕过了源代码的技术会带来维护问题。
反射代码比相应的直接代码更复杂,正如性能比较的代码实例中看到的一样。解决这些问题的最佳方案是保守地使用反射-- 仅在它可以真正增加灵活性的地方记录其在目标类中的使用.
/* *
* @author smart
*/
public class ReflectTest {
public ReflectTest(String value) {
System.out.println("declared value:"+value);
}
public ReflectTest(){ }
public static void main(String[] args) {
ReflectTest.classObject();
ReflectTest.clsssdeclaredObject();
ReflectTest.classMothodObject();
}
/**
* 直接创建对象调用方法 */
private static void classObject(){
try {
//参数值
Object []value=new Object[]{"1","2"};
//参数类型
Class par[]=new Class[]{String.class,String.class};
Class c=Class.forName("zjnx.sibas.ReflectTest");
//创建类对象
Object object=c.newInstance();
//得到方法对象
Method method=object.getClass().getDeclaredMethod("towStringEq", par);
//调用方法
boolean flag=Boolean.parseBoolean(method.invoke(object, value).toString());
System.out.println("flag:"+flag);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 调用有参构造函数,调用方法
*/
private static void clsssdeclaredObject(){
try {
//参数值
Object []value=new Object[]{new String[]{"1","2","3"},new Integer(1)};
//参数类型
Class par[]=new Class[]{String[].class,int.class};
//构造函数参数
Class declared[]=new Class[]{String.class};
//构造函数值
Object declaredValue[]=new Object[]{"1"};
Class c=Class.forName("zjnx.sibas.ReflectTest");
//初始化构造函数
Constructor constructor = c.getDeclaredConstructor(declared);
//新建对象
Object object=constructor.newInstance(declaredValue);
//得到方法对象
Method method=object.getClass().getDeclaredMethod("printValue", par);
//调用方法
method.invoke(object, value);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void classMothodObject(){
try {
//构造函数参数
//参数值
Object []value=new Object[]{new String[]{"1","2","3"},new Integer(1)};
//参数类型
Class par[]=new Class[]{String[].class,int.class};
//构造函数参数
Object declared[]=new Object[]{"1"};
//类完整路径
String className="zjnx.sibas.ReflectTest";
Object object=ReflectTest.getInstance(className, declared);
//Object object=ReflectTest.getInstance(className, null);
//得到方法对象
Method method=object.getClass().getDeclaredMethod("printValue", par);
//调用方法
method.invoke(object, value);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 按照指定的类名称 并按照指定的参数进行构造而获取实例
*
* 限制性条件为: objects 中的className 必须和构造参数中的类型一致。
*
* 如果Object 中存在 超越 参数类型的方法将导致初始化失败!!!! 例如 getInstance("Cr", {new
* Integer(2)}); 将无法应用在构造 方法 Cr(Number num)
* @param className 类名称
* @param objects 构造方法的类名称
* @return 返回构造出的实例
* @throws Exception 初始化错误时返回此项例外
*/
public static final Object getInstance(String className, Object[] objects) {
try {
Class clz = Class.forName(className);
if (objects==null ||objects.length==0)
{
return clz.newInstance() ;
}
Class[] paramClaszz = new Class[objects.length];
for (int i = 0; i < objects.length; i++) {
paramClaszz[i] = objects[i].getClass();
}
Constructor constructor = clz.getDeclaredConstructor(paramClaszz);
return constructor.newInstance(objects);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 是不是某个类的实例
* @param obj 实例
* @param cls 类
* @return 如果 obj 是此类的实例,则返回 true
*/
public boolean isInstance(Object obj, Class cls) {
return cls.isInstance(obj);
}
/**
* 得到某个对象的公共属性
* @param owner, fieldName
* @return 该属性对象
* @throws Exception
*/
public Object getProperty(Object owner, String fieldName) {
try {
Class ownerClass = owner.getClass();
Field field = ownerClass.getField(fieldName);
Object property = field.get(owner);
return property;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 得到某类的静态公共属性
* @param className 类名
* @param fieldName 属性名
* @return 该属性对象
* @throws Exception
*/
public Object getStaticProperty(String className, String fieldName){
try {
Class ownerClass = Class.forName(className);
Field field = ownerClass.getField(fieldName);
Object property = field.get(ownerClass);
return property;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private boolean towStringEq(String str1,String str2) {
System.out.println("str1:"+str1+" str2:"+str2);
if (str1.equals(str2)) {
return true;
}else{
return false;
}
}
private void printValue(String []arr,int i) {
System.out.println("i:"+i);
for (int j = 0; j < arr.length; j++) {
System.out.println("arr["+j+"]:"+arr[j]);
}
}
}