国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

從零開始學習 Java:簡單易懂的入門指南之反射(三十八)

這篇具有很好參考價值的文章主要介紹了從零開始學習 Java:簡單易懂的入門指南之反射(三十八)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

1. 反射

1.1 反射的概述:

? 專業(yè)的解釋:

? 是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;

? 對于任意一個對象,都能夠調(diào)用它的任意屬性和方法;

? 這種動態(tài)獲取信息以及動態(tài)調(diào)用對象方法的功能稱為Java語言的反射機制。

? 通俗的理解:

  • 利用反射創(chuàng)建的對象可以無視修飾符調(diào)用類里面的內(nèi)容

  • 可以跟配置文件結(jié)合起來使用,把要創(chuàng)建的對象信息和方法寫在配置文件中。

    讀取到什么類,就創(chuàng)建什么類的對象

    讀取到什么方法,就調(diào)用什么方法

    此時當需求變更的時候不需要修改代碼,只要修改配置文件即可。

1.2 學習反射到底學什么?

反射都是從class字節(jié)碼文件中獲取的內(nèi)容。

  • 如何獲取class字節(jié)碼文件的對象
  • 利用反射如何獲取構(gòu)造方法(創(chuàng)建對象)
  • 利用反射如何獲取成員變量(賦值,獲取值)
  • 利用反射如何獲取成員方法(運行)

1.3 獲取字節(jié)碼文件對象的三種方式

  • Class這個類里面的靜態(tài)方法forName(“全類名”)(最常用)
  • 通過class屬性獲取
  • 通過對象獲取字節(jié)碼文件對象

代碼示例:

//1.Class這個類里面的靜態(tài)方法forName
//Class.forName("類的全類名"): 全類名 = 包名 + 類名
Class clazz1 = Class.forName("com.itheima.reflectdemo.Student");
//源代碼階段獲取 --- 先把Student加載到內(nèi)存中,再獲取字節(jié)碼文件的對象
//clazz 就表示Student這個類的字節(jié)碼文件對象。
//就是當Student.class這個文件加載到內(nèi)存之后,產(chǎn)生的字節(jié)碼文件對象


//2.通過class屬性獲取
//類名.class
Class clazz2 = Student.class;

//因為class文件在硬盤中是唯一的,所以,當這個文件加載到內(nèi)存之后產(chǎn)生的對象也是唯一的
System.out.println(clazz1 == clazz2);//true


//3.通過Student對象獲取字節(jié)碼文件對象
Student s = new Student();
Class clazz3 = s.getClass();
System.out.println(clazz1 == clazz2);//true
System.out.println(clazz2 == clazz3);//true

1.4 字節(jié)碼文件和字節(jié)碼文件對象

java文件:就是我們自己編寫的java代碼。

字節(jié)碼文件:就是通過java文件編譯之后的class文件(是在硬盤上真實存在的,用眼睛能看到的)

字節(jié)碼文件對象:當class文件加載到內(nèi)存之后,虛擬機自動創(chuàng)建出來的對象。

? 這個對象里面至少包含了:構(gòu)造方法,成員變量,成員方法。

而我們的反射獲取的是什么?字節(jié)碼文件對象,這個對象在內(nèi)存中是唯一的。

1.5 獲取構(gòu)造方法

規(guī)則:

? get表示獲取

? Declared表示私有

? 最后的s表示所有,復數(shù)形式

? 如果當前獲取到的是私有的,必須要臨時修改訪問權(quán)限,否則無法使用

方法名 說明
Constructor<?>[] getConstructors() 獲得所有的構(gòu)造(只能public修飾)
Constructor<?>[] getDeclaredConstructors() 獲得所有的構(gòu)造(包含private修飾)
Constructor getConstructor(Class<?>… parameterTypes) 獲取指定構(gòu)造(只能public修飾)
Constructor getDeclaredConstructor(Class<?>… parameterTypes) 獲取指定構(gòu)造(包含private修飾)

代碼示例:

public class ReflectDemo2 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        //1.獲得整體(class字節(jié)碼文件對象)
        Class clazz = Class.forName("com.itheima.reflectdemo.Student");


        //2.獲取構(gòu)造方法對象
        //獲取所有構(gòu)造方法(public)
        Constructor[] constructors1 = clazz.getConstructors();
        for (Constructor constructor : constructors1) {
            System.out.println(constructor);
        }

        System.out.println("=======================");

        //獲取所有構(gòu)造(帶私有的)
        Constructor[] constructors2 = clazz.getDeclaredConstructors();

        for (Constructor constructor : constructors2) {
            System.out.println(constructor);
        }
        System.out.println("=======================");

        //獲取指定的空參構(gòu)造
        Constructor con1 = clazz.getConstructor();
        System.out.println(con1);

        Constructor con2 = clazz.getConstructor(String.class,int.class);
        System.out.println(con2);

        System.out.println("=======================");
        //獲取指定的構(gòu)造(所有構(gòu)造都可以獲取到,包括public包括private)
        Constructor con3 = clazz.getDeclaredConstructor();
        System.out.println(con3);
        //了解 System.out.println(con3 == con1);
        //每一次獲取構(gòu)造方法對象的時候,都會新new一個。

        Constructor con4 = clazz.getDeclaredConstructor(String.class);
        System.out.println(con4);
    }
}

1.6 獲取構(gòu)造方法并創(chuàng)建對象

涉及到的方法:newInstance

代碼示例:

//首先要有一個javabean類
public class Student {
    private String name;

    private int age;


    public Student() {

    }

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

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


  //get,set方法

    public String toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }
}



//測試類中的代碼:
//需求1:
//獲取空參,并創(chuàng)建對象

//1.獲取整體的字節(jié)碼文件對象
Class clazz = Class.forName("com.itheima.a02reflectdemo1.Student");
//2.獲取空參的構(gòu)造方法
Constructor con = clazz.getConstructor();
//3.利用空參構(gòu)造方法創(chuàng)建對象
Student stu = (Student) con.newInstance();
System.out.println(stu);


System.out.println("=============================================");


//測試類中的代碼:
//需求2:
//獲取帶參構(gòu)造,并創(chuàng)建對象
//1.獲取整體的字節(jié)碼文件對象
Class clazz = Class.forName("com.itheima.a02reflectdemo1.Student");
//2.獲取有參構(gòu)造方法
Constructor con = clazz.getDeclaredConstructor(String.class, int.class);
//3.臨時修改構(gòu)造方法的訪問權(quán)限(暴力反射)
con.setAccessible(true);
//4.直接創(chuàng)建對象
Student stu = (Student) con.newInstance("zhangsan", 23);
System.out.println(stu);

1.7 獲取成員變量

規(guī)則:

? get表示獲取

? Declared表示私有

? 最后的s表示所有,復數(shù)形式

? 如果當前獲取到的是私有的,必須要臨時修改訪問權(quán)限,否則無法使用

方法名:

方法名 說明
Field[] getFields() 返回所有成員變量對象的數(shù)組(只能拿public的)
Field[] getDeclaredFields() 返回所有成員變量對象的數(shù)組,存在就能拿到
Field getField(String name) 返回單個成員變量對象(只能拿public的)
Field getDeclaredField(String name) 返回單個成員變量對象,存在就能拿到

代碼示例:

public class ReflectDemo4 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        //獲取成員變量對象

        //1.獲取class對象
        Class clazz = Class.forName("com.itheima.reflectdemo.Student");

        //2.獲取成員變量的對象(Field對象)只能獲取public修飾的
        Field[] fields1 = clazz.getFields();
        for (Field field : fields1) {
            System.out.println(field);
        }

        System.out.println("===============================");

        //獲取成員變量的對象(public + private)
        Field[] fields2 = clazz.getDeclaredFields();
        for (Field field : fields2) {
            System.out.println(field);
        }

        System.out.println("===============================");
        //獲得單個成員變量對象
        //如果獲取的屬性是不存在的,那么會報異常
        //Field field3 = clazz.getField("aaa");
        //System.out.println(field3);//NoSuchFieldException

        Field field4 = clazz.getField("gender");
        System.out.println(field4);

        System.out.println("===============================");
        //獲取單個成員變量(私有)
        Field field5 = clazz.getDeclaredField("name");
        System.out.println(field5);

    }
}



public class Student {
    private String name;

    private int age;

    public String gender;

    public String address;


    public Student() {
    }

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


    public Student(String name, int age, String gender, String address) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.address = address;
    }

   //get,set方法

    public String toString() {
        return "Student{name = " + name + ", age = " + age + ", gender = " + gender + ", address = " + address + "}";
    }
}

1.8 獲取成員變量并獲取值和修改值

方法 說明
void set(Object obj, Object value) 賦值
Object get(Object obj) 獲取值

代碼示例:

public class ReflectDemo5 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        Student s = new Student("zhangsan",23,"廣州");
        Student ss = new Student("lisi",24,"北京");

        //需求:
        //利用反射獲取成員變量并獲取值和修改值

        //1.獲取class對象
        Class clazz = Class.forName("com.itheima.reflectdemo.Student");

        //2.獲取name成員變量
        //field就表示name這個屬性的對象
        Field field = clazz.getDeclaredField("name");
        //臨時修飾他的訪問權(quán)限
        field.setAccessible(true);

        //3.設置(修改)name的值
        //參數(shù)一:表示要修改哪個對象的name?
        //參數(shù)二:表示要修改為多少?
        field.set(s,"wangwu");

        //3.獲取name的值
        //表示我要獲取這個對象的name的值
        String result = (String)field.get(s);

        //4.打印結(jié)果
        System.out.println(result);

        System.out.println(s);
        System.out.println(ss);

    }
}


public class Student {
    private String name;
    private int age;
    public String gender;
    public String address;


    public Student() {
    }

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


    public Student(String name, int age, String gender, String address) {
        this.name = name;
        this.age = age;
        this.gender = gender;
        this.address = address;
    }
//get,set 方法
   
    public String toString() {
        return "Student{name = " + name + ", age = " + age + ", gender = " + gender + ", address = " + address + "}";
    }
}

1.9 獲取成員方法

規(guī)則:

? get表示獲取

? Declared表示私有

? 最后的s表示所有,復數(shù)形式

? 如果當前獲取到的是私有的,必須要臨時修改訪問權(quán)限,否則無法使用

方法名 說明
Method[] getMethods() 返回所有成員方法對象的數(shù)組(只能拿public的)
Method[] getDeclaredMethods() 返回所有成員方法對象的數(shù)組,存在就能拿到
Method getMethod(String name, Class<?>… parameterTypes) 返回單個成員方法對象(只能拿public的)
Method getDeclaredMethod(String name, Class<?>… parameterTypes) 返回單個成員方法對象,存在就能拿到

代碼示例:

public class ReflectDemo6 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        //1.獲取class對象
        Class<?> clazz = Class.forName("com.itheima.reflectdemo.Student");


        //2.獲取方法
        //getMethods可以獲取父類中public修飾的方法
        Method[] methods1 = clazz.getMethods();
        for (Method method : methods1) {
            System.out.println(method);
        }

        System.out.println("===========================");
        //獲取所有的方法(包含私有)
        //但是只能獲取自己類中的方法
        Method[] methods2 = clazz.getDeclaredMethods();
        for (Method method : methods2) {
            System.out.println(method);
        }

        System.out.println("===========================");
        //獲取指定的方法(空參)
        Method method3 = clazz.getMethod("sleep");
        System.out.println(method3);

        Method method4 = clazz.getMethod("eat",String.class);
        System.out.println(method4);

        //獲取指定的私有方法
        Method method5 = clazz.getDeclaredMethod("playGame");
        System.out.println(method5);
    }
}

1.10 獲取成員方法并運行

方法

Object invoke(Object obj, Object… args) :運行方法

參數(shù)一:用obj對象調(diào)用該方法

參數(shù)二:調(diào)用方法的傳遞的參數(shù)(如果沒有就不寫)

返回值:方法的返回值(如果沒有就不寫)

代碼示例:

package com.itheima.a02reflectdemo1;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectDemo6 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //1.獲取字節(jié)碼文件對象
        Class clazz = Class.forName("com.itheima.a02reflectdemo1.Student");
		
        //2.獲取一個對象
        //需要用這個對象去調(diào)用方法
        Student s = new Student();
        
        //3.獲取一個指定的方法
        //參數(shù)一:方法名
        //參數(shù)二:參數(shù)列表,如果沒有可以不寫
        Method eatMethod = clazz.getMethod("eat",String.class);
        
        //運行
        //參數(shù)一:表示方法的調(diào)用對象
        //參數(shù)二:方法在運行時需要的實際參數(shù)
        //注意點:如果方法有返回值,那么需要接收invoke的結(jié)果
        //如果方法沒有返回值,則不需要接收
        String result = (String) eatMethod.invoke(s, "重慶小面");
        System.out.println(result);

    }
}



public class Student {
    private String name;
    private int age;
    public String gender;
    public String address;


    public Student() {

    }

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

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

   //get,set 方法

    public String toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }

    private void study(){
        System.out.println("學生在學習");
    }

    private void sleep(){
        System.out.println("學生在睡覺");
    }

    public String eat(String something){
        System.out.println("學生在吃" + something);
        return "學生已經(jīng)吃完了,非常happy";
    }
}

面試題:

? 你覺得反射好不好?好,有兩個方向

? 第一個方向:無視修飾符訪問類中的內(nèi)容。但是這種操作在開發(fā)中一般不用,都是框架底層來用的。

? 第二個方向:反射可以跟配置文件結(jié)合起來使用,動態(tài)的創(chuàng)建對象,動態(tài)的調(diào)用方法。

后記
????????美好的一天,到此結(jié)束,下次繼續(xù)努力!欲知后續(xù),請看下回分解,寫作不易,感謝大家的支持??! ??????
文章來源地址http://www.zghlxwxcb.cn/news/detail-713130.html

到了這里,關(guān)于從零開始學習 Java:簡單易懂的入門指南之反射(三十八)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包