反射
反射允許對封裝類的成員變量、成員方法和構(gòu)造方法的信息進行編程訪問
成員變量:修飾符、名字、類型、get/set值
構(gòu)造方法:修飾符、名字、形參、創(chuàng)建對象
成員方法:修飾符、名字、形參、返回值、拋出的異常、獲取注解、運行方法
獲取class對象
- Class.forName(“全類名”);全類名是包名加類名
- 類名.class
- 對象.getClass();
在源代碼階段可以使用第一種方法(最常用)
在加載階段可以使用第二種方法(當參數(shù)傳遞)
在運行階段可以使用第三種方法(當已經(jīng)有了這個類的對象的時候才可以調(diào)用)
構(gòu)造方法的對象—Constructor
變量(字段)的對象—Field
成員方法—Method
Class consumer = Class.forName("Consumer");
Constructor[] constructors = consumer.getConstructors();
for (int i = 0; i < constructors.length; i++)
System.out.println(constructors[i]);
Constructor[] declaredConstructors = consumer.getDeclaredConstructors();
Constructor constructor = consumer.getConstructor();
Constructor declaredConstructor = consumer.getDeclaredConstructor();
// consumer.getConstructor(對應(yīng)構(gòu)造函數(shù)的參數(shù)列表);比如說String可以使用String.class
// consumer.getDeclaredConstructor(對應(yīng)構(gòu)造函數(shù)的參數(shù)列表);比如說int,可以使用int.class
Class consumer = Class.forName("Consumer");
Constructor constructor = consumer.getConstructor(String.class);
System.out.println(constructor.getModifiers());//獲取對應(yīng)構(gòu)造函數(shù)的權(quán)限修飾符
上面的方法可以獲取對應(yīng)構(gòu)造方法的權(quán)限修飾符。但是其是以整數(shù)的形式表示出來的:
1024:Abstract
16:Final
512:Interface
256:native
2:private
4:protected
1:public
8:static
2048:strict
32:synchronized
128:transient
64:volatile
Class consumer = Class.forName("Consumer");
Constructor constructor = consumer.getConstructor(String.class);
System.out.println(constructor.getParameterCount());//獲取所需的參數(shù)個數(shù)
Parameter[] parameters = constructor.getParameters();
for (Parameter parameter : parameters) {
System.out.println(parameter);
}//獲取所需的參數(shù)類型
Class consumer = Class.forName("Consumer");
Constructor declaredConstructor = consumer.getDeclaredConstructor(String.class);//獲取私有構(gòu)造方法
declaredConstructor.setAccessible(true);//臨時取消私有的權(quán)限修飾
declaredConstructor.newInstance("張三");//使用私有構(gòu)造方法創(chuàng)建對象實例
獲取成員變量
Class類中的用于獲取成員變量的方法
方法 | 作用 |
---|---|
Field[] getFields() | 返回所有公共的成員變量對象的數(shù)組 |
Field[] getDeclaredFields() | 返回所有成員變量對象的數(shù)組 |
Field getField(String name) | 返回單個公共成員變量的對象 |
Field getDeclaredField(String name) | 返回單個成員變量的對象 |
Field類中用于創(chuàng)建對象的方法
方法 | 作用 |
---|---|
void set(Object o,Object value) | 賦值 |
Object get(Object obj) | 獲取值 |
也可以獲取權(quán)限修飾符,還可以獲取字段類型
也可以暫時修改權(quán)限修飾符,然后可以進行g(shù)et、set方法
獲取成員方法
getMethods獲取的方法包含父類中的方法
Declared不可以獲取父類的,但是可以獲取私有的
反射可以結(jié)合配置文件動態(tài)的創(chuàng)建對象調(diào)用方法。
動態(tài)代理
動態(tài)代理可以無侵入式的為方法增加功能
對象有什么方法想被代理,代理就一定要有對應(yīng)的方法
通常要被代理的方法都放在接口中,兩個類都實現(xiàn)這個接口
Java.lang.reflect.Proxy類:提供了為對象產(chǎn)生代理對象的方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
參數(shù)一:用于指定使用哪一個類加載器,去加載生成的代理類
參數(shù)二:指定接口,這些接口用于指定生成的代理有什么方法
參數(shù)三:用于指定生成的代理對象要干什么事情
下面是一個示例:
方法類:
public class BigStar implements modefier {
String name;
public BigStar() {
}
public BigStar(String name) {
this.name = name;
}
@Override
public String Sing(String songName) {
System.out.println(this.name + "正在唱" + songName);
return "謝謝大家\n";
}
@Override
public String Dance(String danceName) {
System.out.println(this.name + "正在唱" + danceName);
return "謝謝大家\n";
}
/**
* 獲取
*
* @return name
*/
public String getName() {
return name;
}
/**
* 設(shè)置
*
* @param name
*/
public void setName(String name) {
this.name = name;
}
public String toString() {
return "BigStar{name = " + name + "}";
}
}
接口:(寫想要被代理的方法)
public interface modefier {
public abstract String Sing(String name);
public abstract String Dance(String name);
}
代理類:
其中要判斷執(zhí)行為方法附加的功能文章來源:http://www.zghlxwxcb.cn/news/detail-436174.html
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class proxyUtil {
public static modefier CreatProxy(BigStar bs) {
modefier o = (modefier) Proxy.newProxyInstance(proxyUtil.class.getClassLoader(),
new Class[]{modefier.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("Sing".equals(method.getName())) {
System.out.println("唱歌先收錢");
} else if ("Dance".equals(method.getName())) {
System.out.println("跳舞也要收錢");
}
return method.invoke(bs, args);
}
}
);
return o;
}
}
測試類:文章來源地址http://www.zghlxwxcb.cn/news/detail-436174.html
BigStar bs = new BigStar("cxk");
modefier modefier = proxyUtil.CreatProxy(bs);
System.out.println(modefier.Sing("只因你太美"));
到了這里,關(guān)于Java反射和動態(tài)代理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!