您的位置:首页 > 编程语言 > Java开发

记录学习的点滴(Java反射机制)

2017-03-25 22:29 429 查看
Java反射机制

1、定义

在运行状态,对于一个类,能够知道这个类的所有属性和方法。对于一个对象,能够调用它的任意一个属性和方法。

2、作用

.生成动态代理

3、内容

.获取完整的包名类名

.实例化Class对象

.获取父类和接口

.调用类的方法

.调用类的属性
TestReflect.java

package com.test.reflect;

public interface TestReflect {

void sayHello();

}


TestReflectParent.java

package com.test.reflect;

public class TestReflectParent {

public void sayHello(){
System.out.println("Hello World.");
}

}

TestReflectImpl.java

package com.test.reflect;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class TestReflectImpl extends TestReflectParent implements TestReflect {

public static void main(String[] args) throws Exception {
// 获取对象完整的包名和类名
TestReflectImpl reflect = new TestReflectImpl();
String packageName = reflect.getClass().getName();
System.out.println("获取类名包名:" + packageName);

// 实例化Class对象
Class<?> clazz1 = null;
// 常用的方法
clazz1 = Class.forName("com.test.reflect.TestReflectImpl");
Class<?> clazz2 = null;
clazz2 = TestReflectImpl.class;
Class<?> clazz3 = null;
clazz3 = new TestReflectImpl().getClass();
System.out.println("实例化Class对象方法1:" + clazz1);
System.out.println("实例化Class对象方法1:" + clazz2);
System.out.println("实例化Class对象方法1:" + clazz3);

// 获取对象的父类和接口
Class<?> clazz = Class.forName("com.test.reflect.TestReflectImpl");
Class<?> parentClass = clazz.getSuperclass();
System.out.println("获取对象的父类的名称:" + parentClass.getName());
Class<?> intes[] = clazz.getInterfaces();
for (int i = 0; i < intes.length; i++) {
System.out.println("获取对象的接口的名称:" + intes[i].getName());
}

// 实例化默认方法
Class<?> clazzUser = Class.forName("com.test.reflect.TestReflectUser");
TestReflectUser user = (TestReflectUser)clazzUser.newInstance();
user.setUserCode("1000");
user.setUserName("abcd");
System.out.println(user);

// 调用类的方法
Class<?> clazzMethod1 = Class.forName("com.test.reflect.TestReflectImpl");
Method method1 = clazzMethod1.getMethod("TestReflectMethod1");
method1.invoke(clazzMethod1.newInstance());
Class<?> clazzMethod2 = Class.forName("com.test.reflect.TestReflectImpl");
Method method2 = clazzMethod2.getMethod("TestReflectMethod2", String.class, int.class);
method2.invoke(clazzMethod2.newInstance(), "反射机制:方法", 2);

// 操作类的属性
Class<?> clazzProperty = Class.forName("com.test.reflect.TestReflectOther");
Object obj = clazzProperty.newInstance();
// 直接对private属性进行操作
Field field = clazzProperty.getDeclaredField("privateProperty");
field.setAccessible(true);
field.set(obj,
4000
"属性由私有变为公开。");
Method methodPrivateProperty = clazzProperty.getMethod("printPrivateProperty");
methodPrivateProperty.invoke(obj);
}

public void TestReflectMethod1(){
System.out.println("反射机制:方法1");
}

public void TestReflectMethod2(String string, int i){
System.out.println(string + String.valueOf(i));
}

}

操作类的属性的时候,私有属性必须加上field.setAccessible(true),才可以获取私有属性。

TestReflectOther.java

package com.test.reflect;

public class TestReflectOther {

private String privateProperty = "私有属性。";

public void printPrivateProperty(){
System.out.println(privateProperty);
}
}

运行结果:



.动态代理

package com.test.reflect;

public interface TestReflectProxy {

void sayMorning(String param1, String param2, int param3);

}

TestReflectProxyImpl.java

package com.test.reflect;

public class TestReflectProxyImpl implements TestReflectProxy {

@Override
public void sayMorning(String param1, String param2, int param3) {
System.out.println(param1 + param2 + String.valueOf(param3));
}
}
package com.test.reflect;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyInvocationHandler implements InvocationHandler {
private Object obj = null;

public Object bind(Object paramObj) {
this.obj = paramObj;
return Proxy.newProxyInstance(
paramObj.getClass().getClassLoader(), paramObj.getClass().getInterfaces(), this);
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object temp = method.invoke(this.obj, args);
return temp;
}
}
// 动态代理
MyInvocationHandler handler = new MyInvocationHandler();
TestReflectProxy proxy = (TestReflectProxy)handler.bind(new TestReflectProxyImpl());
proxy.sayMorning("Good", "Morning-", 100);

运行结果:

GoodMorning-100

优点:

(1)能够运行时动态获取类的实例,大大提高系统的灵活性和扩展性。

(2)与Java动态编译相结合,可以实现无比强大的功能

缺点:

(1)使用反射的性能较低

(2)使用反射相对来说不安全

(3)破坏了类的封装性,可以通过反射获取这个类的私有方法和属性 (如上面例子,private属性就可以修改。)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: