反射機制在java中的應用
本文主要介紹反射的一些基本概念,基本方法呼叫,和在java中的一些使用,主要是在模式中的使用如 工程模式,動態代理模式,dagger2,Butterknife 等也會用到
反射的基本概念
獲得class<?>的三種方法
Class<?> cls1 = ReflectionActivity.class;
ReflectionActivity activity = new ReflectionActivity();
Class<?> cls2 = activity.getClass();
try {
Class<?> cls3 = Class.forName("com.sun.study.ui.activity.ReflectionActivity" );
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
基本方法羅列
getName():獲得類的完整名字。
newInstance():通過類的不帶引數的構造方法建立這個類的一個物件。
getFields():獲得類的public型別的屬性。
getDeclaredFields():獲得類的所有屬性。
getMethods():獲得類的public型別的方法。
getDeclaredMethods():獲得類的所有方法。
getMethod(String name, Class[] parameterTypes):獲得類的特定方法。
getModifiers ()和Modifier.toString():獲得屬修飾符,例如private,public,static等
getReturnType():獲得方法的返回型別
getParameterTypes():獲得方法的引數型別
getConstructors():獲得類的public型別的構造方法。
getConstructor(Class[] parameterTypes):獲得類的特定構造方法。
getSuperclass():獲取某類的父類
getInterfaces():獲取某類實現的介面
getAnnotation()獲得註解
羅列一個列的所有方法
private void getMethodsInfo() {
Class<ReflectionActivity> cls = ReflectionActivity.class;
Method[] methods = cls.getDeclaredMethods();
if (methods == null) return;
StringBuilder sb = new StringBuilder();
for (Method method:methods) {
sb.append(Modifier.toString(method.getModifiers())).append(" ");
sb.append(method.getReturnType()).append(" ");
sb.append(method.getName()).append("(");
Class[] parameters = method.getParameterTypes();
if (parameters != null) {
for (int i=0; i<parameters.length; i++) {
Class paramCls = parameters[i];
sb.append(paramCls.getSimpleName());
if (i < parameters.length - 1) sb.append(", ");
}
}
sb.append(")\n\n");
}
tvInfo.setText(sb.toString());
}
獲得類的屬性,並修改器屬性的值
private void modifyFieldValue() {
Class<ReflectionActivity> cls = ReflectionActivity.class;
Field[] fields = cls.getDeclaredFields();
if (fields == null) return;
StringBuilder sb = new StringBuilder();
sb.append("獲得類的所有屬性資訊:\n\n");
for (Field field:fields) {
sb.append(Modifier.toString(field.getModifiers())).append(" ");
sb.append(field.getType().getSimpleName()).append(" ");
sb.append(field.getName()).append(";");
sb.append("\n\n");
}
try {
sb.append("屬性i的預設值:i = ");
Field f = cls.getDeclaredField("i");
sb.append(f.getInt("i")).append("\n\n");
f.set("i", 100);
sb.append("屬性i修改後的值:i = ");
sb.append(f.getInt("i")).append("\n\n");
} catch (Exception e) {
e.printStackTrace();
}
tvInfo.setText(sb.toString());
toolbar.setSubtitle("修改型別Int屬性i的值");
}
註解(Annotation),也叫元資料。一種程式碼級別的說明。它是JDK 1.5及以後版本引入的一個特性,與類、介面、列舉是在同一個層次。它可以宣告在包、類、欄位、方法、區域性變數、方法引數等的前面,用來對這些元素進行說明,註釋。
自定義一個clinckEvent
@Target(ElementType.ANNOTATION_TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface clinckEvent
{
Class<?> listener();
String listenerMethod();
String methodName();
}
再接著定義一個
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@clinckEvent(listener = View.OnClickListener.class, listenerMethodr = "setOnClickListener", methodName = "onClick")
public @interface OnClick
{
int[] value();
}
程式碼中使用
class Activity{
@OnClick({ R.id.id_btn, R.id.id_btn02 })
public void clickBtnInvoked(View view)
}
通過反射獲得註解
Class<? extends Activity> clazz = activity.getClass();
Method[] methods = clazz.getMethods();
//遍歷所有的方法
for (Method method : methods)
{
Annotation[] annotations = method.getAnnotations();
//拿到方法上的所有的註解
for (Annotation annotation : annotations)
Class<? extends Annotation> annotationType = annotation
.annotationType();
//拿到註解上的註解
clinckEvent getAnnotation = annotationType
.getAnnotation(clinckEvent.class);
if (getAnnotation != null)
{
//取出設定監聽器的名稱,監聽器的型別,呼叫的方法名
String listenerSetter = getAnnotation
.listenerSetter();
Class<?> listener = getAnnotation.listener();
String methodName = getAnnotation.methodName();
}
//拿到Onclick註解中的value方法
Method aMethod = annotationType
.getDeclaredMethod("value");
//取出所有的viewId
int[] viewIds = (int[]) aMethod
.invoke(annotation, null);
}
/**
* 注入主佈局檔案
*
* @param activity
*/
private static void injectContentView(Activity activity)
{
Class<? extends Activity> clazz = activity.getClass();
// 查詢類上是否存在ContentView註解
ContentView contentView = clazz.getAnnotation(ContentView.class);
if (contentView != null)// 存在
{
int contentViewLayoutId = contentView.value();
try
{
Method method = clazz.getMethod(METHOD_SET_CONTENTVIEW,
int.class);
method.setAccessible(true);
method.invoke(activity, contentViewLayoutId);
} catch (Exception e)
{
e.printStackTrace();
}
}
}
1**工程模式中使用**
public class ProductFatory<T> {
public <T> T Object getInstance(String className){
Object instance=null;
try {
Class cls=Class.forName(className);
instance= cls.newInstance();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return instance;
}
- 代理模式中使用
動態代理
InvocationHandler
Proxy
public interface Subject
{
public void doSomething();
}
public interface Advice
{
public void exe();
}
public class RealAdvice implements Advice
{
public void exe()
{
//驗證條件是否滿足
}
}
public class RealSubject implements Subject
{
public void doSomething()
{
System.out.println( "call doSomething()" );
}
}
public class ProxyHandler implements InvocationHandler
{
private Object proxied;
public ProxyHandler( Object proxied )
{
this.proxied = proxied;
}
public Object invoke( Object proxy, Method method, Object[] args ) throws Throwable
{
//在轉調具體目標物件之前,可以執行一些功能處理
Boolean isFlag=“增加自己的判斷邏輯”
if(isFlag){
new RealAdvice().exe();
}
//轉調具體目標物件的方法
return method.invoke( proxied, args);
//在轉調具體目標物件之後,可以執行一些功能處理
}
}
client 程式碼
public class Client
{
public static void main( String args[] )
{
RealSubject real = new RealSubject();
Subject proxySubject = (Subject)Proxy.newProxyInstance(Subject.class.getClassLoader(),
new Class[]{Subject.class},
new ProxyHandler(real));
proxySubject.doSomething();
}
安卓中的BIndler 原理Aidl 通訊
Router.build(uri).callback(new RouteCallback() { // 新增結果回撥
@Override
public void callback(RouteResult state, Uri uri, String message) {
if (state == RouteResult.SUCCEED) {
Toast.makeText(MainActivity.this, "succeed: " + uri.toString(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "error: " + uri + ", " + message, Toast.LENGTH_SHORT).show();
}
}
}).go(this);
增加了注入模組
結合這邊文章看
會有意想不到的收穫
Activity注入控制元件view 和點選事件
/**
* 我們自己的類
*/
@Module
public class MarkCarModule {
public MarkCarModule(){ }
@Provides Engine provideEngine(){
return new Engine("gear");
}
}
/**
* Dagger2生成的工廠類
*/
public final class MarkCarModule_ProvideEngineFactory implements Factory<Engine> {
private final MarkCarModule module;
public MarkCarModule_ProvideEngineFactory(MarkCarModule module) {
assert module != null;
this.module = module;
}
@Override
public Engine get() {
return Preconditions.checkNotNull(
module.provideEngine(), "Cannot return null from a [email protected] @Provides method");
}
public static Factory<Engine> create(MarkCarModule module) {
return new MarkCarModule_ProvideEngineFactory(module);
}
/** Proxies {@link MarkCarModule#provideEngine()}. */
public static Engine proxyProvideEngine(MarkCarModule instance) {
return instance.provideEngine();
}
}
/**
* 我們自己的類
*/
@Component(modules = {MarkCarModule.class})
public interface CarComponent {
void inject(Car car);
}
用到了建造者模式
/**
* Dagger2生成的CarComponent實現類
*/
public final class DaggerCarComponent implements CarComponent {
private Provider<Engine> provideEngineProvider;
private MembersInjector<Car> carMembersInjector;
private DaggerCarComponent(Builder builder) {
assert builder != null;
initialize(builder);
}
public static Builder builder() {
return new Builder();
}
public static CarComponent create() {
return builder().build();
}
@SuppressWarnings("unchecked")
private void initialize(final Builder builder) {
this.provideEngineProvider = MarkCarModule_ProvideEngineFactory.create(builder.markCarModule);
this.carMembersInjector = Car_MembersInjector.create(provideEngineProvider);
}
@Override
public void inject(Car car) {
carMembersInjector.injectMembers(car);
}
public static final class Builder {
private MarkCarModule markCarModule;
private Builder() {}
public CarComponent build() {
if (markCarModule == null) {
this.markCarModule = new MarkCarModule();
}
return new DaggerCarComponent(this);
}
public Builder markCarModule(MarkCarModule markCarModule) {
this.markCarModule = Preconditions.checkNotNull(markCarModule);
return this;
}
}
}
ublic final class Car_MembersInjector implements MembersInjector<Car> {
private final Provider<Engine> engineProvider;
public Car_MembersInjector(Provider<Engine> engineProvider) {
assert engineProvider != null;
this.engineProvider = engineProvider;
}
public static MembersInjector<Car> create(Provider<Engine> engineProvider) {
return new Car_MembersInjector(engineProvider);
}
@Override
public void injectMembers(Car instance) {
if (instance == null) {
throw new NullPointerException("Cannot inject members into a null reference");
}
instance.engine = engineProvider.get();
}
public static void injectEngine(Car instance, Provider<Engine> engineProvider) {
instance.engine = engineProvider.get();
}
}
相關推薦
Java反射機制的簡單應用
mod arc pos ret system containe java反射機制 track san 一直感覺java的反射機制非常強大,可是可用的地方不多。在android學習的時候。一直想實現掛斷電話的功能,可是
Java反射機制的深入應用
前言 在上一篇文章中介紹了Java反射的基本概念以及基本應用,不熟悉的朋友可以點這裡 本篇文章將重點介紹反射機制的深入應用 反射除了可以取得一個類的完整結構外,還可以呼叫類中的指定方法或指定屬性,並且可以通過反射完成對陣列的操作。 通
java反射機制的業務應用場景-1
好久不寫東西,最近整理之前的東西時發現以前有一些寫好的東西,其實都是一些學習筆記或是對某個技術理解的一些感想,覺得很有意思,拿出來和大家分享一下。 這篇文章我們先來說一下java的反射機制,java的反射機制其實在1.2的時候就已經有了,那時我們
快取機制:java中快取的原理
外存: 也就是我們經常說的(CDEF盤的大小)外儲存器是指除計算機記憶體及CPU快取以外的儲存器,此類儲存器一般斷電後仍然能儲存資料。常見的外儲存器有硬碟、軟盤、光碟、U盤等,一般的軟體都是安裝在外存中 記憶體: 記憶體是計算機中重要的部件之一,它是與CPU進行
Java反射之——Java中Class類的使用
Java語言中,萬事萬物皆物件,但是靜態成員、基本的資料型別(基本的資料型別也有自己的包裝類)等並不是物件,因為靜態的變數和函式屬於類,我們可以通過 類.靜態變數 / 類.靜態函式等方式呼叫。 public class Test { private st
在Java中應用工廠(Factory)模式
基本概念 Factory Method是一種建立性模式,它定義了一個建立物件的介面,但是卻讓子類來決定具體例項化哪一個類.當一個類無法預料要建立哪種類的物件或是一個類需要 由子類來指定建立的物件時我們就需要用到Factory Method 模式了.簡單說來,Factory M
在Java中應用檔案鎖
檔案鎖在作業系統中是很平常的事情,當多個執行的程式需要併發修改同一個檔案時,程式之間需要某種機制來進行通訊,使用檔案鎖可以有效的阻止多個程序併發修改同一個檔案,所以現在的大部分作業系統都提供了檔案鎖的功能。 從JDK1.4的NIO開始,Java開始提
art中的monitor機制--java 中 Synchronized與art Monitor的關係
在java 世界中我們使用synchronized 關鍵字對需要做同步的程式碼進行上鎖操作,來保證同一時刻只有一個執行緒可以對加鎖程式碼段進行同步操作.synchronized機制實現依賴對應虛擬機器的實現,在android中實現該功能的就是art的Monitor部分. 1
Java反射機制在工廠模式中的應用
在本篇文章中就不詳細介紹工廠模式,主要介紹一下反射在工廠模式中的使用,讓讀者對反射機制帶來的好處有更深的認識。 首先看一下簡單工廠模式 簡單工廠模式(simple factory)是類的建立模式,又叫靜態工廠方法(static factory method)模式。 簡單工廠
反射機制在java中的應用
本文主要介紹反射的一些基本概念,基本方法呼叫,和在java中的一些使用,主要是在模式中的使用如 工程模式,動態代理模式,dagger2,Butterknife 等也會用到 反射的基本概念 獲得class<?>的三種方法 Class<
Java中的反射機制
導致 buffer 自己 net -- 實例 reflect .config lang 學習Java的同學註意了!!! 學習過程中遇到什麽問題或者想獲取學習資源的話,歡迎加入Java學習交流群,群號碼:618528494 我們一起學Java!
Java中的反射機制(一)
erl void port 令行 sage [0 ray 輸出 我們 基本概念 在Java運行時環境中,對於任意一個類,能否知道這個類有哪些屬性和方法?對於任意一個對象,能否調用它的任意一個方法? 答案是肯定的。 這種動態獲取類的信息以及動態調用對象的方法的功能
Java反射機制demo(五)—獲得並調用一個類中的方法
color 擁有 oca logs over super getmethod equals() bool 這個demo在使用反射機制操作屬性之前,主要原因是因為在.class文件字節碼中,方法排在屬性的前面。 1,獲得一個類中的方法 先看一下方法和運行結果。獲取所有的方
JAVA中反射機制五(JavaBean的內省與BeanUtils庫)
getc ron 輸出結果 下載 比較 static 完成 自動完成 規則 內省(Introspector) 是Java 語言對JavaBean類屬性、事件的一種缺省處理方法。 JavaBean是一種特殊的類,主要用於傳遞數據信息,這種類中的方法主要用於訪問私有的
JAVA中反射機制六(java.lang.reflect包)
instance 檢查 item 類繼承 final win 基類 cte member 一、簡介 java.lang.reflect包提供了用於獲取類和對象的反射信息的類和接口。反射API允許對程序訪問有關加載類的字段,方法和構造函數的信息進行編程訪問。它允許在安全限制
Java中反射機制詳解
turn face instance java struct () 分享 2.6 一個 序言 在學習java基礎時,由於學的不紮實,講的實用性不強,就覺得沒用,很多重要的知識就那樣一筆帶過了,像這個馬上要講的反射機制一樣,當時學的時候就忽略了,到後來學習
Java反射機制能夠獲取的信息,與應用
rri 代理 pan [] reflect 語言 子類 list tro 一、什麽是Java反射機制? 【1】反射機制是在運行狀態中,對於任何一個類,都能夠知道這個類的所有屬性和方法; 【2】對於任意一個對象,都能夠調用它的任意一個屬性和方法; 像這種動態獲取類的信
【Java入門提高篇】Day13 Java中的反射機制
== getchar 復制對象 enc 類型判斷 amt sim 博客 contains 前一段時間一直忙,所以沒什麽時間寫博客,拖了這麽久,也該更新更新了。最近看到各種知識付費的推出,感覺是好事,也是壞事,好事是對知識沈澱的認可與推動,壞事是感覺很多人忙於把自己的知識
java反射機制應用之動態代理
代理類 過多 size bject interface 並且 編譯期 代理 抽象 1.靜態代理類和動態代理類區別 靜態代理:要求被代理類和代理類同時實現相應的一套接口;通過代理類的對象調用重寫接口的方法時,實際上執行的是被代理類的同樣的 方法的調用。 動態代理:在程序運
java反射機制——獲取位元組碼對應類中的函式
package cn.itcast.reflect.demo; import java.lang.reflect.Constructor; import java.lang.reflect.Method; //獲取類中的函式 public class ReflectDemo4 { public