Java的反射機制之反向抽菸

show me the code and take to me,作的出來更要說的明白
GitHub項目JavaHouse同步收錄
喜歡就點個讚唄! 你的支持是我分享的動力!html

引入

反射是一種不按套路處出牌的機制。一般咱們接觸的方式都是 "正射",暫且起這個名字。雖然咱們用的少,可是反射其實就在咱們平常開發中。好比咱們常見的空指針異常,或者是 Spring 的各類註解配置建立對象等等。java

正常操做

ReflectTest reflectTest = new ReflectTest();
reflectTest.setName("boolenbl公衆號");
System.out.println(reflectTest.getName());

通常咱們使用上面方法建立對象以及初始化屬性。而且有嚴格的訪問規則。可是反射就反其道爲之。他利用 Class、 Method、 Field等類,隨意建立對象,獲取公有、私有的方法,獲取私有的、共有的方法。git

Class 類

Class 類只有私有的構造方法,所以咱們不能初始化該對對象,不過 Class 類也不是給咱們使用的。 Class 類只能被 JVM 調用。有圖有真相:github

獲取Class 類

有三種方法能夠獲取到 Class 類。代碼以下:微信

// 方法1
System.out.println(ReflectTest.class);
// 方法2
System.out.println(new ReflectTest().getClass());
// 方法3  包名+類名 (JDBC那種操做) 有異常
System.out.println(Class.forName("基礎.ReflectTest"));
// 獲取類名
System.out.println(ReflectTest.class.getName());

獲取方法

利用該方法能夠無視訪問規則,獲取全部的方法。代碼以下:post

System.out.println(Arrays.toString(ReflectTest.class.getDeclaredMethods()));

獲取屬性

利用該方法能夠無視訪問規則,獲取全部的屬性。代碼以下:測試

System.out.println(Arrays.toString(ReflectTest.class.getDeclaredFields()));

獲取構造器

reflectTestClass.getConstructor();

從正常到異常(反射操做對象)

Class<ReflectTest> reflectTestClass = ReflectTest.class;
Method method = reflectTestClass.getMethod("setName", String.class);
Constructor<ReflectTest> constructor = reflectTestClass.getConstructor();
reflectTest = constructor.newInstance();
method.invoke(reflectTest, "公衆號");
System.out.println(reflectTest.getName());

完整代碼

package 基礎;

import lombok.Data;
import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @Description: 反射測試
 * @Author: boolean
 * @Date: 2019/12/26 17:01
 */
@Data
public class ReflectTest {
    private String name;
    private String pass;

    @Test
    public void test() throws NoSuchMethodException, ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException {
        /**
         * 前提獲取 Class 類
         */
        // 方法1
        System.out.println(ReflectTest.class);
        // 方法2
        System.out.println(new ReflectTest().getClass());
        // 方法3  包名+類名 (JDBC那種操做) 有異常
        System.out.println(Class.forName("基礎.ReflectTest"));
        // 獲取類名
        System.out.println(ReflectTest.class.getName());
        // 獲取方法
        System.out.println(Arrays.toString(ReflectTest.class.getDeclaredMethods()));
        // 獲取屬性
        System.out.println(Arrays.toString(ReflectTest.class.getDeclaredFields()));

        // 正常建立對象並初始化
        ReflectTest reflectTest = new ReflectTest();
        reflectTest.setName("boolenbl公衆號");
        System.out.println(reflectTest.getName());

        // 反射建立對象並初始化
        Class<ReflectTest> reflectTestClass = ReflectTest.class;
        Constructor<ReflectTest> constructor = reflectTestClass.getConstructor();
        reflectTest = constructor.newInstance();
        Method method = reflectTestClass.getMethod("setName", String.class);
        method.invoke(reflectTest, "公衆號");
        System.out.println(reflectTest.getName());
    }

    public void test1(){

    }

    public void test2(){

    }

    public void test3(){

    }
}

運行結果

class 基礎.ReflectTest
class 基礎.ReflectTest
class 基礎.ReflectTest
基礎.ReflectTest
[public boolean 基礎.ReflectTest.equals(java.lang.Object), public java.lang.String 基礎.ReflectTest.toString(), public int 基礎.ReflectTest.hashCode(), public java.lang.String 基礎.ReflectTest.getName(), public void 基礎.ReflectTest.setName(java.lang.String), public void 基礎.ReflectTest.test() throws java.lang.NoSuchMethodException,java.lang.ClassNotFoundException,java.lang.IllegalAccessException,java.lang.reflect.InvocationTargetException,java.lang.InstantiationException, protected boolean 基礎.ReflectTest.canEqual(java.lang.Object), public void 基礎.ReflectTest.test3(), public void 基礎.ReflectTest.test2(), public void 基礎.ReflectTest.test1(), public java.lang.String 基礎.ReflectTest.getPass(), public void 基礎.ReflectTest.setPass(java.lang.String)]
[private java.lang.String 基礎.ReflectTest.name, private java.lang.String 基礎.ReflectTest.pass]
boolenbl公衆號
公衆號

參考

https://www.cnblogs.com/chanshuyi/p/head_first_of_reflection.html
sczyh30.com/posts/Java/java-reflection-1/
https://juejin.im/post/598ea9116fb9a03c335a99a4指針

關注微信公衆號,隨時移動端閱讀

公衆號.jpg

相關文章
相關標籤/搜索