一個java反射的簡單實例

一、反射的定義

JAVA反射機制是在運行狀態中,可以構造任意一個類的對象,都能夠了解這個類的所有屬性和方法;
對於任意一個對象,都能夠調用它的任意方法和屬性;
這種動態獲取信息以及動態調用對象方法的功能稱爲java語言的反射機制。

二、反射的優點

提高了程序的靈活性和擴展性,降低模塊的耦合性,提高自身的適應能力。
可以讓程序創建和控制任何類的對象,無需提前硬編碼目標類。
能夠在運行時構造一個類的對象、判斷一個類所具有的成員變量和方法、調用一個對象的方法。
是構建框架技術的基礎所在,使用反射可以避免將代碼寫死在框架中。

三、反射的侷限性

反射操作的效率要比正常操作效率低很多。
使用反射通常需要程序的運行沒有安全方面的限制。
反射代碼破壞了Java程序結構的抽象性,反射允許代碼執行一些通常不被允許的操作,所以使用反射有可能會導致意想不到的後果。

四、反射機制的相關類

類名 用途
Class類 代表類的實體,在運行的Java應用程序中表示類和接口
Field類 代表類的成員變量(成員變量也稱爲類的屬性)
Method類 代表類的方法
Constructor類 代表類的構造方法

Class類

Class獲得類相關的方法

方法 用途
asSubclass(Class<U> clazz) 把傳遞的類的對象轉換成代表其子類的對象
Cast 把對象轉換成代表類或是接口的對象
getClassLoader() 獲得類的加載器
getClasses() 返回一個數組,數組中包含該類中所有公共類和接口類的對象
getDeclaredClasses() 返回一個數組,數組中包含該類中所有類和接口類的對象
forName(String className) 根據類名返回類的對象
getName() 獲得類的完整路徑名字
newInstance() 創建類的實例
getPackage() 獲得類的包
getSimpleName() 獲得類的名字
getSuperclass() 獲得當前類繼承的父類的名字
getInterfaces() 獲得當前類實現的類或是接口

Class獲得類中屬性相關的方法

方法 用途
getField(String name) 獲得某個公有的屬性對象
getFields() 獲得所有公有的屬性對象
getDeclaredField(String name) 獲得某個屬性對象
getDeclaredFields() 獲得所有屬性對象

Class獲得類中註解相關的方法

方法 用途
getAnnotation(Class<A> annotationClass) 返回該類中與參數類型匹配的公有註解對象
getAnnotations() 返回該類所有的公有註解對象
getDeclaredAnnotation(Class<A> annotationClass) 返回該類中與參數類型匹配的所有註解對象
getDeclaredAnnotations() 返回該類所有的註解對象

Class獲得類中構造器相關的方法

方法 用途
getConstructor(Class...<?> parameterTypes) 獲得該類中與參數類型匹配的公有構造方法
getConstructors() 獲得該類的所有公有構造方法
getDeclaredConstructor(Class...<?> parameterTypes) 獲得該類中與參數類型匹配的構造方法
getDeclaredConstructors() 獲得該類所有構造方法

Class獲得類中方法相關的方法

方法 用途
getMethod(String name, Class...<?> parameterTypes) 獲得該類某個公有的方法
getMethods() 獲得該類所有公有的方法
getDeclaredMethod(String name, Class...<?> parameterTypes) 獲得該類某個方法
getDeclaredMethods() 獲得該類所有方法

Class類中其他重要的方法

方法 用途
isAnnotation() 如果是註解類型則返回true
isAnnotationPresent(Class<? extends Annotation> annotationClass) 如果是指定類型註解類型則返回true
isAnonymousClass() 如果是匿名類則返回true
isArray() 如果是一個數組類則返回true
isEnum() 如果是枚舉類則返回true
isInstance(Object obj) 如果obj是該類的實例則返回true
isInterface() 如果是接口類則返回true
isLocalClass() 如果是局部類則返回true
isMemberClass() 如果是內部類則返回true

Field類

Field代表類的成員變量

方法 用途
equals(Object obj) 屬性與obj相等則返回true
get(Object obj) 獲得obj中對應的屬性值
set(Object obj, Object value) 設置obj中對應屬性值

Method類

Method代表類的方法。

方法 用途
invoke(Object obj, Object... args) 傳遞object對象及參數調用該對象對應的方法

Constructor類

Constructor代表類的構造方法。

方法 用途
newInstance(Object... initargs) 根據傳遞的參數創建類的對象

五、反射的簡單實例

被反射的類Student

package com.xiaoxiao9575.reflectdemo;

import android.util.Log;

import androidx.annotation.NonNull;

/**
 * author: xiaoxiao9575
 * email:  [email protected]
 * csdn:   https://blog.csdn.net/weixin_40998254
 * github: https://github.com/xiaoxiao9575
 * createTime:  2020/5/29 11:25 AM
 */
public class Student {
    private String name;
    private String sex;
    private int age;
    private static String info = "私有屬性";

    public Student() {
    }

    private Student(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    private String logInfo(String str){
        Log.e("info", "logInfo: 私有方法"+ str);
        return "私有方法"+ str;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                '}';
    }
}

簡單的反射用例

package com.xiaoxiao9575.reflectdemo;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

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

public class MainActivity extends AppCompatActivity {

    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textView);
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Test4();
            }
        });
    }

    /**
     * 反射過程
     */
    private void Test1(){
        try {
            Class<?> classStudent = Class.forName("com.xiaoxiao9575.reflectdemo.Student");
            Object obj = classStudent.newInstance();
            Student student = (Student) obj;
            student.setName("張三");
            student.setSex("男");
            student.setAge(18);
            Log.e("TAG", "Test1: =========="+student.toString() );
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 通過反射創建對象
     */
    private void Test2(){
        try {
            Student student = (Student) Class.forName("com.xiaoxiao9575.reflectdemo.Student").newInstance();
            student.setName("張三");
            student.setSex("男");
            student.setAge(18);
            Log.e("TAG", "Test2: =========="+student.toString() );
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 反射私有構造
     */
    private void Test3(){
        try {
            Class<?> classStudent = Class.forName("com.xiaoxiao9575.reflectdemo.Student");
            Constructor<?> declaredConstructor = classStudent.getDeclaredConstructor(String.class, String.class, int.class);
            declaredConstructor.setAccessible(true);
            Object obj = declaredConstructor.newInstance("李四", "女", 16);
            Student student = (Student) obj;
            Log.e("TAG", "Test3: =========="+student.toString() );
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 反射私有屬性
     */
    private void Test4(){
        try {
            Class<?> classStudent = Class.forName("com.xiaoxiao9575.reflectdemo.Student");
            Object obj = classStudent.newInstance();
            Field info = classStudent.getDeclaredField("info");
            info.setAccessible(true);
            String s = (String) info.get(obj);
            Log.e("TAG", "Test4: =========="+s );
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 反射私有方法
     */
    private void Test5(){
        try {
            Class<?> classStudent = Class.forName("com.xiaoxiao9575.reflectdemo.Student");
            Method logInfo = classStudent.getDeclaredMethod("logInfo", String.class);
            logInfo.setAccessible(true);
            Object object = classStudent.newInstance();
            String test = (String) logInfo.invoke(object, "test");
            Log.e("info", "Test5: =========="+test );
        } catch (Exception e) {
            Log.e("info", "Test5: =========="+e.getMessage() );
            e.printStackTrace();
        }
    }
}

參考文獻

百度百科

Java高級特性——反射

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章