淺談Java反射機制 之 使用類的 屬性、方法和構造函數


前面兩篇我們總結了Java反射機制如何獲取類的字節碼,如何獲取構造函數,屬性和方法,

這篇我們將進一步驗證如何使用我們獲取到的屬性、方法以及構造函數

1、使用 反射 獲取到的 屬性

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;

public class Test08 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

        //加載Class對象
        //會報出不存在該類的異常
        Class c=Class.forName("com.reflection.model.Student");
        //類名
        System.out.println("類名:"+c.getSimpleName());
        //類的包名
        System.out.println("類的包名:"+c.getPackage());

        System.out.println("================使用獲取到的字段=================");
        //根據字段名獲取字段
        Object object= c.getConstructor().newInstance();

        //獲取公共字段
        Field field1=c.getField("name");
        //設置字段值
        field1.set(object,"Not_Copy");
        System.out.println("-----------------"+field1.getName()+"-------------");
        System.out.println("name字段的值:"+field1.get(object));
        System.out.println("name字段類型:"+field1.getType());
        System.out.println("name字段修飾符:"+field1.getModifiers());



        //私有字段
        Field field2=c.getDeclaredField("loginName");
        //開啟 private 權限的方問權限
        field2.setAccessible(true);
        //設置字段值
        field2.set(object,"Login_Not_Copy");
        System.out.println("-----------------"+field2.getName()+"-------------");
        System.out.println("loginName字段的值:"+field2.get(object));
        System.out.println("loginName字段類型:"+field2.getType());
        System.out.println("loginName字段修飾符:"+field2.getModifiers());


        //私有字段
        Field field3=c.getDeclaredField("age");
        //開啟 protected 權限的方問權限
        field3.setAccessible(true);
        //設置字段值
        field3.set(object,23);
        System.out.println("-----------------"+field3.getName()+"-------------");
        System.out.println("age字段的值:"+field3.get(object));
        System.out.println("age字段類型:"+field3.getType());
        System.out.println("age字段修飾符:"+field3.getModifiers());


        Field field4=c.getDeclaredField("Birthday");//私有字段
        //開啟 默認 權限的方問權限
        field4.setAccessible(true);
        //設置字段值
        field4.set(object,new Date());
        System.out.println("-----------------"+field4.getName()+"-------------");
        System.out.println("Birthday字段的值:"+field4.get(object));
        System.out.println("Birthday字段類型:"+field4.getType());
        System.out.println("Birthday字段修飾符:"+field4.getModifiers());
    }
}

 

結果:

類名:Student
類的包名:package com.reflection.model
================使用獲取到的字段=================
-----------------name-------------
name字段的值:Not_Copy
name字段類型:class java.lang.String
name字段修飾符:1
-----------------loginName-------------
loginName字段的值:Login_Not_Copy
loginName字段類型:class java.lang.String
loginName字段修飾符:2
-----------------age-------------
age字段的值:23
age字段類型:class java.lang.Integer
age字段修飾符:4
-----------------Birthday-------------
Birthday字段的值:Mon Jul 22 21:28:02 CST 2019
Birthday字段類型:class java.util.Date
Birthday字段修飾符:0

結論:由代碼 反射獲取到的屬性的  private、private 和 默認權限 都需要使用 暴力反射 ( .setAccessible(true) )來開啟范圍權限,才能訪問。

2、使用 反射 獲取到的 方法

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;

public class Test08 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

        //加載Class對象
        //會報出不存在該類的異常
        Class c=Class.forName("com.reflection.model.Student");
       
        System.out.println("================使用獲取到的方法=================");

        Method method1=c.getMethod("method1", String.class);
        //執行方法
        Object invoke1 =method1.invoke(object,"method1");
        System.out.println("-----------------"+method1.getName()+"-------------");
        System.out.println("method1方法的返回參數列表:"+method1.getParameterTypes());
        System.out.println("method1字段修飾符:"+method1.getModifiers());
        System.out.println("method1字段修飾符:"+method1.getReturnType());
        System.out.println("方法的返回值:"+invoke1);

        Method method2=c.getDeclaredMethod("method2");
        //開啟private權限的方問權限
        method2.setAccessible(true);
        //執行方法
        Object invoke2 =method2.invoke(object,null);
        System.out.println("-----------------"+method2.getName()+"-------------");
        System.out.println("method2方法的返回參數列表:"+method2.getParameterTypes());
        System.out.println("method2字段修飾符:"+method2.getModifiers());
        System.out.println("method2字段修飾符:"+method2.getReturnType());
        System.out.println("方法的返回值:"+invoke2);


        Method method3=c.getDeclaredMethod("method3", String.class, Integer.class, Date.class);
        //開啟默認權限的方問權限
        method3.setAccessible(true);
        //執行方法
        Object invoke3= method3.invoke(object,"No_Copy",23,new Date());
        System.out.println("-----------------"+method3.getName()+"-------------");
        System.out.println("method3方法的返回參數列表:"+method3.getParameterTypes());
        System.out.println("method3字段修飾符:"+method3.getModifiers());
        System.out.println("method3字段修飾符:"+method3.getReturnType());
        System.out.println("方法的返回值:"+invoke3);

        Method method4=c.getDeclaredMethod("method4");
        //開啟 protected 權限的方問權限
        method4.setAccessible(true);
        //執行方法
        Object invoke4= method4.invoke(object,null);
        System.out.println("-----------------"+method4.getName()+"-------------");
        System.out.println("method4方法的返回參數列表:"+method4.getParameterTypes());
        System.out.println("method4字段修飾符:"+method4.getModifiers());
        System.out.println("method4字段修飾符:"+method4.getReturnType());
        System.out.println("方法的返回值:"+invoke4);

    }
}

結果:

================使用獲取到的方法=================
public 修飾的方法:method1
-----------------method1-------------
method1方法的返回參數列表:[Ljava.lang.Class;@14ae5a5
method1字段修飾符:1
method1字段修飾符:class java.lang.String
方法的返回值:method1
private 修飾的方法:method2
-----------------method2-------------
method2方法的返回參數列表:[Ljava.lang.Class;@7f31245a
method2字段修飾符:2
method2字段修飾符:class java.lang.String
方法的返回值:method2
protected 修飾的方法 method3 
 name:No_Copy age:23 birthday:Mon Jul 22 21:28:02 CST 2019
-----------------method3-------------
method3方法的返回參數列表:[Ljava.lang.Class;@6d6f6e28
method3字段修飾符:0
method3字段修飾符:class java.lang.String
方法的返回值:No_Copy 23 Mon Jul 22 21:28:02 CST 2019
protected 修飾的方法:method4
-----------------method4-------------
method4方法的返回參數列表:[Ljava.lang.Class;@135fbaa4
method4字段修飾符:4
method4字段修飾符:class java.lang.String
方法的返回值:method4

結論:由代碼 反射獲取到方法 的  private、private 和 默認權限 都需要使用 暴力反射 ( .setAccessible(true) )來開啟范圍權限,才能訪問。

2、使用 反射 獲取到的 構造函數

import com.reflection.model.Student;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;

public class Test08 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

        //加載Class對象
        //會報出不存在該類的異常
        Class c=Class.forName("com.reflection.model.Student");
        System.out.println(Student.class.getSuperclass().getName());
        System.out.println("================使用獲取到的構造方法=================");
        //調用默認的構造方法
        Object object1= c.getConstructor().newInstance();
        //指定要調用構造方法的參數 參數:指定每個參數的類型
        Constructor constructor = c.getConstructor(String.class,String.class,Integer.class,Date.class);

        //利用構造constructor創建新實例 並傳參調用此構造函數
        Student stu = (Student) constructor.newInstance("Not_Copy","not_copy",25,new Date());

        System.out.println(stu);
    }
}

結果:

================使用獲取到的構造方法=================
Student{name='Not_Copy', loginName='not_copy', age=25, Birthday=Mon Jul 22 21:49:12 CST 2019}

 

貼上 使用的 Student  和  People類:

People類

public class People {
    public String head;
    public String foot;
}

Student類:

import java.util.Date;

public class Student extends People{

    public String name;

    private String loginName;

    protected Integer age;

    Date Birthday;

    public Student(){
        super();
    }

    private Student(String name){
        this.name=name;
    }

    private Student(Integer age){
        this.age=age;
    }

    private Student(Date Birthday){
        this.Birthday=Birthday;
    }

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

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

    public Student(String name,Date Birthday){
        this.name=name;
        this.Birthday=Birthday;
    }

    public Student(Date Birthday,String name){
        this.name=name;
        this.Birthday=Birthday;
    }

    public Student(Integer age,Date Birthday){
        this.age=age;
        this.Birthday=Birthday;
    }

    public Student(Date Birthday,Integer age){
        this.age=age;
        this.Birthday=Birthday;
    }

    public Student(String name,String loginName){
        this.name=name;
        this.loginName=loginName;
    }

    public Student(String name,Integer age,Date Birthday){
        this.age=age;
        this.name=name;
        this.Birthday=Birthday;
    }

    public Student(String name,String loginName,Integer age,Date Birthday){
        this.name=name;
        this.loginName=loginName;
        this.age=age;
        this.Birthday=Birthday;
    }


    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    public Date getBirthday() {
        return Birthday;
    }

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

    public String method1(String str){
        System.out.println("public 修飾的方法:"+str);
        return str;
    }

    private String method2(){
        System.out.println("private 修飾的方法:"+"method2");
        return "method2";
    }

    String  method3(String name,Integer age,Date birthday){
        System.out.println("protected 修飾的方法 method3 \n name:"+name+" age:"+age+" birthday:"+birthday);
        return name+" "+age+" "+birthday;
    }

    protected String method4(){
        System.out.println("protected 修飾的方法:"+"method4");
        return "method4";
    }

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM