Java 反射

目錄

 

簡介

Class類

反射--獲取Class對象的三種方式:

反射--獲取指定構造方法創建一個對象

反射--獲取屬性值,爲指定屬性賦值

反射--普通方法的調用

反射--static方法調用

反射--破壞泛型檢查

關於泛型--請參考博文


簡介

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

反射機制中,一個類的屬性,方法,構造方法,以及註釋 都有與之對應的類對其進行描述,反射的核心思想就是把原有類的屬性、方法、構造方法、註釋乃至包命用一個又一個的類去拆解。

 

Class類

  1. final類。
  2. 運行中的類、接口是Class類的實例。
  3. 枚舉是一種類、註解是一種接口、數組將被映射成一個Class類對象,具有相同元素類型與維度的數組將共享該對象。
  4. boolean, byte, char, short, int, long, float, and double,void 也是Class的實例對象。
  5. Class 沒有公共構造方法。Class 對象是在加載類時由 Java 虛擬機以及通過調用類加載器中的defineClass 方法自動構造的。也就是這不需要我們自己去處理創建,JVM已經幫我們創建好了。

 

反射--獲取Class對象的三種方式:

(別說創建Class對象、因爲Class類的對象早就在內存中存在了,我們所要做的就是拿到這些對象直接使用)

package com.knowledge.system.java_system.reflection_system.bok_instance;

public class Student {
    private Integer age;
    private String name;
    private String address;
    private boolean sex;

    public Student() {
        System.out.println("公有無參構造函數");
    }

    private  Student(Integer age) {
        this.age = age;
        System.out.println("私有一個參數構造函數");
    }

    protected Student(String name) {
        this.name = name;
        System.out.println("受保護一個參數構造函數");
    }

    public Student(boolean sex) {
        this.sex = sex;
        System.out.println("公有一個參數構造函數");
    }

    public Student(Integer age, String name, String address, boolean sex) {
        this.age = age;
        this.name = name;
        this.address = address;
        this.sex = sex;
    }

    public void testFun1(String msg){
        System.out.println(msg);
    }

    public void testFun2(String msg){
        System.out.println(msg);
    }

    public void testFun3(String msg){
        System.out.println(msg);
    }

    public Integer getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public boolean isSex() {
        return sex;
    }

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

    public static void main(String[] args) {
        System.out.println("main 方法執行了。");
    }

    public static void testMain(String msg){
        System.out.println("static  方法執行了,入參"+msg);
    }
}
package com.knowledge.system.java_system.reflection_system.bok_instance;

import com.alibaba.fastjson.JSON;
import lombok.SneakyThrows;
import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * @program: demo-pom
 * @description:
 * @author: bo.hu
 * @create: 2020-03-05 16:59
 **/

public class ReflectionTest {
    @Test
    public void testGetClassObject(){
        Student student=new Student();
        Class clz=student.getClass();//對象角度---不常用,對象都有了還反射干啥
        Class clz2=Student.class;//類角度---業務開發中常用(但要導包,依賴太強,不導包編譯會出問題)
        Class clz3=null;//靜態方法角度---常用(全路徑名可以通過配置文件搞進去)
        try {
            clz3=Class.forName("com.knowledge.system.java_system.reflection_system.bok_instance.Student");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        System.out.println(clz.getName());
        System.out.println(JSON.toJSONString(clz3.getPackage()));
        System.out.println("constructors  "+JSON.toJSONString(clz.getDeclaredConstructors()[0]));
        System.out.println("fields  "+JSON.toJSONString(clz.getDeclaredFields()[0]));
        System.out.println("method  "+JSON.toJSONString(clz.getDeclaredMethods()[0]));
        System.out.println("annotation  "+JSON.toJSONString(clz.getDeclaredAnnotations()[0]));
    }

}

 

反射--獲取指定構造方法創建一個對象

  1. Constructor  :可以調用任何構造方法,可強行訪問

  2. Class.newInstance:只能夠調用   共有  無參構造方法。當無參方法私有時,報錯:java.lang.IllegalAccessException

    @Test
    public void testConstructors() throws IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException {
        //通過反射獲取指定的構造方法--主要用來創建對象
        Class clz=Student.class;
        Constructor con=clz.getDeclaredConstructor(Integer.class);
        if(!con.isAccessible()){
            con.setAccessible(true);
        }
        Student student= (Student) con.newInstance(23);
        System.out.println("student:"+JSON.toJSONString(student));

        Student student1= (Student) clz.newInstance();
        System.out.println("student1:"+JSON.toJSONString(student1));
    }

 

反射--獲取屬性值,爲指定屬性賦值

    @Test
    public void testField() throws NoSuchFieldException, IllegalAccessException {
        //獲取指定屬性值
        Student student=new Student();
        student.setAge(20);
        Class clz=Student.class;
        Field f=clz.getDeclaredField("age");
        if(!f.isAccessible()){
            f.setAccessible(true);
        }
        Object value=f.get(student);
        System.out.println(value);
        //設置指定屬性值
        Field field=clz.getDeclaredField("name");
        if(!field.isAccessible()){
            field.setAccessible(true);
        }
        field.set(student,"afgahgdahgahdhas");
        System.out.println(JSON.toJSONString(student));
    }

 

反射--普通方法的調用

   @Test
    public void testMethod() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class clz=Student.class;
        Student student=new Student();
        Method method=clz.getDeclaredMethod("setName",String.class);
        if(!method.isAccessible()){
            method.setAccessible(true);
        }
        method.invoke(student,"adghashasd;gasdhgasdfgiophpuioh");
        System.out.println(JSON.toJSONString(student, SerializerFeature.WriteMapNullValue));
    }

 

反射--static方法調用

    @Test
    public void testMethod() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class clz=Student.class;
        Student student=new Student();
        Method method=clz.getDeclaredMethod("testMain", String.class);
        if(!method.isAccessible()){
            method.setAccessible(true);
        }
        method.invoke(null,"adghashasd;gasdhgasdfgiophpuioh");
        System.out.println(JSON.toJSONString(student, SerializerFeature.WriteMapNullValue));
    }

    @Test
    public void testMain() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class clz=Student.class;
        Method m1=clz.getDeclaredMethod("main",String[].class);
        m1.invoke(null,(Object)new String[]{"a","a","a"});
    }

 

反射--破壞泛型檢查

    @SneakyThrows
    @Test
    public void testTEF(){
        List <String> arrayList=new ArrayList <>();
        arrayList.add("adddd");
        arrayList.add("bbbbbb");
        Class clz=arrayList.getClass();
        Method m=clz.getDeclaredMethod("add",Object.class);
        m.invoke(arrayList,1000);
        System.out.println(JSON.toJSONString(arrayList));
    }

關於泛型--請參考博文

Java 泛型使用

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