***

17513 ワード

Java反射メカニズムとは?
JAVA反射機構は運転状態において、いずれのクラスに対しても、このクラスのすべての属性と方法を知ることができる.任意のオブジェクトに対して、その任意のメソッドを呼び出すことができます.このような動的取得および動的呼び出しオブジェクトのメソッドの機能をJavaの反射メカニズムと呼ぶ.
反射メカニズムにはどのような機能がありますか?
実行時にいずれかのオブジェクトが属するクラスを判定する.
実行時に任意のクラスのオブジェクトを構築します.
実行時に任意のクラスが持つメンバー変数と方法を判定する.
実行時に任意のオブジェクトを呼び出す方法.
動的エージェントを生成します.
Java反射メカニズムクラス:
java.lang.Class; //  
java.lang.reflect.Constructor;//     
java.lang.reflect.Field; //       
java.lang.reflect.Method;//    
java.lang.reflect.Modifier;//    

Java反射メカニズムの実装:
1.)classオブジェクトの取得
//          getClass   Person person = new Person();
Class<?> class1 = person.getClass();
//          class  
class1 = Person.class;
try {
    //        Class      ——forName()   
    class1 = Class.forName("com.whoislcj.reflectdemo.Person");
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

2.)classオブジェクトの要約情報を取得する
boolean isPrimitive = class1.isPrimitive();//         
boolean isArray = class1.isArray();//        
boolean isAnnotation = class1.isAnnotation();//        
boolean isInterface = class1.isInterface();//        
boolean isEnum = class1.isEnum();//        
boolean isAnonymousClass = class1.isAnonymousClass();//          
boolean isAnnotationPresent = class1.isAnnotationPresent(Deprecated.class);//            

String className = class1.getName();//  class         
Package aPackage = class1.getPackage();//  class    
String simpleName = class1.getSimpleName();//  class  
int modifiers = class1.getModifiers();//  class    

Class<?>[] declaredClasses = class1.getDeclaredClasses();//   
Class<?> declaringClass = class1.getDeclaringClass();//   

3.)classオブジェクトの属性、メソッド、コンストラクション関数などを取得する
Field[] allFields = class1.getDeclaredFields();//  class       
Field[] publicFields = class1.getFields();//  class   public  
try {
    Field ageField = class1.getDeclaredField("age");//  class    
    Field desField = class1.getField("des");//  class   public  
} catch (NoSuchFieldException e) {
    e.printStackTrace();
}

Method[] methods = class1.getDeclaredMethods();//  class         
Method[] allMethods = class1.getMethods();//  class               

Class parentClass = class1.getSuperclass();//  class     
Class<?>[] interfaceClasses = class1.getInterfaces();//  class       

Constructor<?>[] allConstructors = class1.getDeclaredConstructors();//  class           
Constructor<?>[] publicConstructors = class1.getConstructors();//  class  public    
try {
    Constructor<?> constructor = class1.getDeclaredConstructor(new Class[]{String.class});//          
    Constructor publicConstructor = class1.getConstructor(new Class[]{});//       public    
} catch (NoSuchMethodException e) {
    e.printStackTrace();
}

Annotation[] annotations = class1.getAnnotations();//  class       
Annotation annotation = class1.getAnnotation(Deprecated.class);//  class      

Type genericSuperclass = class1.getGenericSuperclass();//  class         Type
Type[] interfaceTypes = class1.getGenericInterfaces();//  class        type  

4.)classオブジェクト動的生成
//      Class    newInstance()     Object obj = class1.newInstance(); //             Constructor  ,    Constructor   newInstance()    
Constructor<?> constructor = class1.getDeclaredConstructor(new Class[]{String.class});//          
obj = constructor.newInstance(new Object[]{"lcj"});

5)動的呼び出し関数
try { //       : newInstance()  
    Object obj = class1.newInstance();
    //        Person   
    boolean isInstanceOf = obj instanceof Person;
    //             Method  
    Method method = class1.getDeclaredMethod("setAge", new Class[]{int.class});
    //            
    method.invoke(obj, 28);
    method = class1.getDeclaredMethod("getAge");
    Object result = method.invoke(obj, new Class[]{});
} catch (InstantiationException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (NoSuchMethodException e) {
    e.printStackTrace();
} catch (InvocationTargetException e) {
    e.printStackTrace();
}

6)反射機構による汎用型の取得
例えば次のような構造
//People  public class People<T> {}
//Person   People 
public class Person<T> extends People<String> implements PersonInterface<Integer> {}
//PersonInterface  
public interface PersonInterface<T> {}

汎用タイプの取得
Person<String> person = new Person<>();
//          getClass  
Class<?> class1 = person.getClass();
Type genericSuperclass = class1.getGenericSuperclass();//  class         Type
Type[] interfaceTypes = class1.getGenericInterfaces();//  class        Type  

getComponentType(genericSuperclass);
getComponentType(interfaceTypes[0]);
getComponentType     
private Class<?> getComponentType(Type type) { Class<?> componentType = null;
if (type instanceof ParameterizedType) {
    //getActualTypeArguments()               Type      。
    Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
    if (actualTypeArguments != null && actualTypeArguments.length > 0) {
    componentType = (Class<?>) actualTypeArguments[0];
    }
} else if (type instanceof GenericArrayType) {
    //                          
    componentType = (Class<?>) ((GenericArrayType) type).getGenericComponentType();
} else {
    componentType = (Class<?>) type;
}
return componentType;
}

6)反射機構による注記情報の取得
        Method       
try { //             Method  
    Method method = class1.getDeclaredMethod("jumpToGoodsDetail", new Class[]{String.class, String.class});
    Annotation[] annotations1 = method.getAnnotations();//           
    Annotation annotation1 = method.getAnnotation(RouterUri.class);//         
    TypeVariable[] typeVariables1 = method.getTypeParameters();
    Annotation[][] parameterAnnotationsArray = method.getParameterAnnotations();//          
    Class<?>[] parameterTypes = method.getParameterTypes();//      class  
    Type[] genericParameterTypes = method.getGenericParameterTypes();//       type  
    Class<?> returnType = method.getReturnType();//         
    int modifiers = method.getModifiers();//         
} catch (NoSuchMethodException e) {
    e.printStackTrace();
}

反射メカニズムの適用シーン:
逆コンパイルなどの逆コード
注釈と結合するフレームワーク、例えばRetrofit 単純な反射機構はフレームワーク、例えばEventBus 2を適用する.x
動的生成クラスフレームワーク、例えばGson 反射メカニズムのメリットとデメリット:
メリット:
実行期間タイプの判断、動的クラスロード、動的エージェントは反射を使用します.
欠点:
パフォーマンスは問題であり、反射は一連の解釈操作に相当し、jvmにやるべきことを通知し、直接javaコードよりもパフォーマンスが遅い.
まとめ:
Javaの反射メカニズムは普段の業務開発の過程ではあまり使われていませんが、いくつかの基礎フレームワークの構築に広く応用されています.今日は簡単にまとめて勉強しましたが、未知の知識などがたくさんあります.