成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

Java Core-五.繼承-詳解反射機(jī)制

soasme / 3548人閱讀

摘要:減少,減輕壓力。實(shí)現(xiàn)測(cè)試類(lèi)無(wú)參構(gòu)造器無(wú)參構(gòu)造器含參構(gòu)造器含參構(gòu)造器忽略訪問(wèn)的安全檢查無(wú)參構(gòu)造器含參構(gòu)造器獲取方法規(guī)則類(lèi)獲取修飾的指定方法含超類(lèi)獲取修飾的指定方法含超類(lèi)類(lèi)獲取指定方法包括修飾,暴力反射,不

五.繼承

繼承 定義:基于已有的類(lèi)構(gòu)造新類(lèi)

反射 定義:在程序運(yùn)行期間發(fā)現(xiàn)更多的類(lèi)以及屬性的能力

多態(tài) 定義:一個(gè)對(duì)象變量可以指示多種實(shí)際類(lèi)型的現(xiàn)象

動(dòng)態(tài)綁定 定義:在運(yùn)行時(shí)能夠自動(dòng)選擇調(diào)用方法的現(xiàn)象

5.1 類(lèi)、超類(lèi)和子類(lèi) 5.1.2 覆蓋方法

規(guī)則

超類(lèi)和子類(lèi)中的方法簽名相同(方法名和參數(shù)列表),返回值類(lèi)型需要保證一樣或者是返回值類(lèi)型的子類(lèi)(協(xié)變返回類(lèi)型)

覆蓋和重載的區(qū)別

覆蓋是方法簽名相同

重載是方法名相同,參數(shù)列表必須不同,對(duì)返回類(lèi)型,訪問(wèn)修飾符,異常聲明沒(méi)有任何限制

5.1.6 方法調(diào)用流程

圖解

5.1.7 阻止繼承:final類(lèi)和方法

規(guī)則

類(lèi)用final修飾后,無(wú)法被繼承,其中的方法也自動(dòng)用final修飾。域不包括

方法用final修飾后,子類(lèi)無(wú)法覆蓋當(dāng)前方法

5.1.8 強(qiáng)制類(lèi)型轉(zhuǎn)換

注意

強(qiáng)制類(lèi)型轉(zhuǎn)換前,使用instanceof方法判斷是否為所屬類(lèi)型

5.2 Object:所有類(lèi)的超類(lèi)

注意:只有基本類(lèi)型不是對(duì)象

5.2.1 equals

特點(diǎn)

自反性:x為任何非空引用,x.equals(x)應(yīng)該返回true

對(duì)稱(chēng)性:對(duì)于任何引用x,y,當(dāng)且僅當(dāng)x.equals(y)返回true,則y.equals(x)返回也為true

傳遞性:對(duì)于任何引用x,y,z,如果x.equals(y)返回true,y.equals(z)返回true,則x.equals(z)返回也為true

一致性:如果x,y引用的對(duì)象沒(méi)有變化,則x.equals(y)應(yīng)一直返回true

equals和等號(hào)的區(qū)別——重點(diǎn)

等號(hào)(==)

基本數(shù)據(jù)類(lèi)型(也稱(chēng)原始數(shù)據(jù)類(lèi)型) :byte,short,char,int,long,float,double,boolean。他們之間的比較,應(yīng)用雙等號(hào)(==),比較的是他們的值。

引用數(shù)據(jù)類(lèi)型:當(dāng)他們用(==)進(jìn)行比較的時(shí)候,比較的是他們?cè)趦?nèi)存中的存放地址(確切的說(shuō),是堆內(nèi)存地址)

equals

方法的初始默認(rèn)行為是比較對(duì)象的內(nèi)存地址值

在一些類(lèi)庫(kù)當(dāng)中這個(gè)方法被重寫(xiě)了,如String、Integer、Date,比較對(duì)象的成員變量值是否相同

合理的equals重寫(xiě)邏輯

顯示參數(shù)聲明為Object

判斷是否引用同一對(duì)象

判斷是否為空

判斷是否屬于同一類(lèi)

將比較對(duì)象轉(zhuǎn)換成相應(yīng)類(lèi)型的變量

域的比較

5.2.3 hashCode方法

散列碼(hash code) 定義:是由對(duì)象導(dǎo)出的一個(gè)整型值

注意

字符串和基本數(shù)據(jù)類(lèi)型的包裝類(lèi)創(chuàng)建的對(duì)象存在hashCode相同的情況,因?yàn)槭怯蓛?nèi)容導(dǎo)出的

public class TestHashCode {
    public static void main(String[] args) {
        String s1 = "a";
        String s2 = "a";
        Integer i = 10;
        Integer k = 10;
        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
        System.out.println(s1.equals(s2));
        System.out.println(i.hashCode());
        System.out.println(k.hashCode());
        System.out.println(i.equals(k));
    }
}/* output
97
97
true
10
10
true
*/

如果重新定義equals方法,就必須重新定義hashCode方法,以便用戶可以將對(duì)象插入到散列表中。如果重新定義,會(huì)出現(xiàn)equals相等,hashCode不等——考點(diǎn)

5.2.4 toString方法

用途:返回表示對(duì)象值的字符串

注意

toString方法常見(jiàn)的原因:當(dāng)對(duì)象與一個(gè)字符串通過(guò)操作符+連接,編譯將自動(dòng)使用toString方法

public class TestToString {
    String name = "asd";

    public static void main(String[] args) {
        TestToString testToString = new TestToString();
        System.out.println(testToString+"jkl");
    }
}/* output
Five.TestToString.TestToString@1218025cjkl
*/

建議重寫(xiě)toString方法,默認(rèn)調(diào)用的方法可讀性較差

public class TestToString {
    String name = "asd";

    @Override public String toString() {
        return "TestToString{" + "name="" + name + """ + "}";
    }

    public static void main(String[] args) {
        TestToString testToString = new TestToString();
        System.out.println(testToString+"jkl");
    }
}/* output
TestToString{name="asd"}jkl
*/

5.2.5 getClass方法

用途:返回包含對(duì)象信息的類(lèi)對(duì)象

public class TestToString {
    String name = "asd";

    public static void main(String[] args) {
        TestToString testToString = new TestToString();
        System.out.println(testToString.getClass());
    }
}/* output
class Five.TestToString.TestToString
*/

5.3 泛型數(shù)組列表

泛型 定義:Java 泛型的參數(shù)只可以代表類(lèi),不能代表個(gè)別對(duì)象

1.ArrayList

定義:采用類(lèi)型參數(shù)的泛型類(lèi)

// 使用方法
ArrayList staff = new ArrayList();
// 泛型的類(lèi)型為Employee

規(guī)則

使用add方法增加新數(shù)據(jù)。如果空間用盡,則自動(dòng)創(chuàng)建更大的數(shù)組,并將原數(shù)據(jù)拷貝到更大的數(shù)組中

使用size方法獲取實(shí)際元素?cái)?shù)量

使用trimToSize將清除多余的存儲(chǔ)空間

使用get和set方法訪問(wèn)和設(shè)置元素

注意

數(shù)組列表和數(shù)組大小的核心區(qū)別:數(shù)組分配100的空間是已經(jīng)在內(nèi)存中存在的;數(shù)組列表在僅是具備存儲(chǔ)100的潛力,即使是完成了初始化之后

使用時(shí),指定泛型的類(lèi)型。因?yàn)椴恢付ǚ盒皖?lèi)型,存儲(chǔ)和修改數(shù)據(jù)接受任意類(lèi)型對(duì)象,因?yàn)槭褂玫氖荗bject

5.4 對(duì)象包裝器和自動(dòng)裝箱 1.自動(dòng)裝箱

裝箱 定義:基本數(shù)據(jù)類(lèi)型變換為基本類(lèi)型的包裝類(lèi)

// 裝箱
public class TestAutoBoxing {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(5); // 等于 list.add(Integer.valueOf(5));
    }
}/* conclusion
1.list中的元素為Integer類(lèi)型
2.當(dāng)使用.add()方法添加時(shí),被添加的類(lèi)型為基本類(lèi)型int
3.因此將自動(dòng)變換為 list.add(Integer.valueOf(5))
*/

注意

自動(dòng)裝箱規(guī)范要求boolean,byte,char小于等于127,介于-128至127之間的short和int被包裝到固定的對(duì)象中。

原因是:IntegerCache.low 默認(rèn)是-128;IntegerCache.high默認(rèn)是127,超出范圍的將創(chuàng)建對(duì)象存儲(chǔ),不然直接返回值。減少new,減輕jvm壓力。

public class TestAutoBoxing {
    public static void main(String[] args) {
                // 使用包裝類(lèi)
        Integer a = 127;
        Integer b = 127;
        Integer c = 128;
        Integer d = 128;
        System.out.println("a == b:"+(a == b));
        System.out.println("c == d:"+(c == d));
    }
}/* output
a == b:true
c == d:false
*/

由于包裝器類(lèi)引用可以為null,因此會(huì)出現(xiàn)NullPointerException

如果混合使用Integer和Double,Integer會(huì)拆箱,提升為double,然后裝箱為Double

自動(dòng)拆箱和自動(dòng)裝箱是編譯器認(rèn)可的,不是虛擬機(jī)。

2.自動(dòng)拆箱

拆箱 定義:將包裝類(lèi)數(shù)據(jù)拆成基本類(lèi)型數(shù)據(jù)

public class TestAutoBoxing {
    public static void main(String[] args) {
        // 裝箱
        ArrayList list = new ArrayList();
        list.add(5);
        // 拆箱
        int intType = list.get(0); // 等于 int intType = list.get(0).intValue();
    }
}/* conclusion
1.list中的元素為Integer類(lèi)型
2.當(dāng)使用.get()方法獲取時(shí),獲得的值類(lèi)型為Integer
3.因此將自動(dòng)變換為 int intType = list.get(0).intValue();
*/

5.5 參數(shù)可變的方法

參數(shù)可變 定義:支持用可變的參數(shù)數(shù)量調(diào)用的方法

格式

// 使用 ...
Double ... args

// 同時(shí)接收多個(gè)參數(shù)
System.out.printf("%d %s",n,"name");

// 底層實(shí)現(xiàn)代碼
public PrintStream printf(String format, Object ... args) {
        return format(format, args);
    }
/* conclusion
1.“String format”為格式字符串,“Object ... args”為Object對(duì)象的數(shù)組,因此數(shù)量可變
*/

public class TestFindMax {
    static void findMax(Object ... args){
        double largest = Double.NEGATIVE_INFINITY;
        for (Object y: args
             ) {
                Double z = (Double) y;
                if (z > largest)
                    largest = z;
        }
        System.out.println(largest);
    }

    public static void main(String[] args) {
        TestFindMax.findMax(3.454,34.3);
    }
}

5.6 枚舉類(lèi)

格式

enum EnumName{
    MAX,MIN,DEDIUM;
}

注意

枚舉類(lèi)中是實(shí)例,因此能夠創(chuàng)建實(shí)例中的變量,但必須使用構(gòu)造方法賦值

public class TestEnum {
     public enum Size{
        MAX("max",3),MIN("min",1),MEDIUM("medium",2);
        // 成員變量
        private String name;
        private int num;
        // 成員變量的構(gòu)造方法
        Size(String name , int i) {
            this.name = name;
            this.num = i;
        }
    }
    public static void main(String[] args) {
        // 在同一個(gè)類(lèi)中,因此可以訪問(wèn)私有的成員變量name
        String name = Size.MAX.name;
        System.out.println(name);
    }
}

5.7 反射——重點(diǎn)

反射 定義:支持分析類(lèi)的能力的程序

反射機(jī)制:將類(lèi)中的各個(gè)部分封裝成其他對(duì)象

原理圖

獲取Class對(duì)象的三種方式

Class.forName("全類(lèi)名"):在第一階段,將字節(jié)碼文件加載進(jìn)內(nèi)存,然后獲取Class對(duì)象

多用于配置文件

類(lèi)名.class:在第二階段,通過(guò)類(lèi)名的class屬性

多用于參數(shù)的傳遞

對(duì)象.getClass():在第三階段,通過(guò)Object的getClass方法獲取

多用于對(duì)象的字節(jié)碼的獲取

public class TestReflectionClass {
    public static void main(String[] args) throws Exception {
        /*
        Class對(duì)象獲取的三種方式
        1.通過(guò)Class.forclass("全類(lèi)名")獲取
        2.通過(guò)類(lèi)名.class()獲取
        3.通過(guò)對(duì)象.getClass()方法
        */
        // 1.通過(guò)Class.forclass("全類(lèi)名")獲取
        Class cls1 = Class.forName("Five.TestReflection.Person");
        System.out.println(cls1);
        // 2.通過(guò)類(lèi)名.class()獲取
        Class cls2 = Person.class;
        System.out.println(cls2);
        // 3.通過(guò)對(duì)象.getClass()方法
        Person p = new Person();
        Class cls3 = p.getClass();
        System.out.println(cls3);
        // 4.比較三個(gè)class引用所指向的是否為同一個(gè)Class對(duì)象
        System.out.println("比較三個(gè)class引用所指向的是否為同一個(gè)Class對(duì)象");
        System.out.println("cls1 == cls2:"+(cls1 == cls2));
        System.out.println("cls1 == cls2:"+(cls1 == cls3));
    }
}/* output
class Five.TestReflection.Person
class Five.TestReflection.Person
class Five.TestReflection.Person
比較三個(gè)class引用所指向的是否為同一個(gè)Class對(duì)象
cls1 == cls2:true
cls1 == cls2:true
*/

注意

同一個(gè)字節(jié)碼文件(.class)在一次程序運(yùn)行中只加載一次,所以三種獲取Class對(duì)象的方式獲取到的Class對(duì)象都是同一個(gè)

用途

在運(yùn)行時(shí)分析類(lèi)的能力

在運(yùn)行時(shí)操作對(duì)象

實(shí)現(xiàn)通用的數(shù)組操作代碼

利用Mehtod對(duì)象,類(lèi)似C++中的函數(shù)指針

5.7.1 Class類(lèi) 1.Class對(duì)象中的功能
1.1獲取成員變量值

規(guī)則

Field[] getFields():獲取所有的public修飾的成員變量(包括超類(lèi))

Field getField():獲取指定的public修飾的成員變量(包括超類(lèi))

Field[] getDeclaredFields():獲取所有的成員變量(即使是private修飾,暴力反射)

Field getDeclaredField():獲取指定的成員變量(即使是private修飾,暴力反射)

注意

getFields和getDeclaredFields()獲取時(shí),getFields能夠同時(shí)獲取到超類(lèi)和子類(lèi)中的public變量,getDeclaredFields()只能獲取到子類(lèi)中的所有訪問(wèn)修飾類(lèi)型的變量

// 超類(lèi)
public class Father {
    // 成員變量
    private String priFatherName;
    private int priFatherAge;
    public String pubFatherName;
    public int pubFatherAge;
}

// 子類(lèi)
public class Son extends Father {
    // 成員變量
    private String priSonName;
    private int priSonAge;
    public String pubSonName;
    public int pubSonAge;
}
// 測(cè)試類(lèi)
package Five.TestReflection;

import java.lang.reflect.Field;

public class TestField {
    public static void main(String[] args) throws Exception {
        /*
        getField和getDeclaredField
         */
        // getField
        System.out.println("--測(cè)試getField");
        Field[] field1 = Son.class.getFields();
        for (Field f : field1) {
            System.out.println(f);
        }
        // getDeclaredField
        System.out.println("--測(cè)試getDeclaredField");
        Field[] field2 = Son.class.getDeclaredFields();
        for (Field f : field2) {
            System.out.println(f);
        }}}
/* output
--測(cè)試getField
public java.lang.String Five.TestReflection.Son.pubSonName
public int Five.TestReflection.Son.pubSonAge
public java.lang.String Five.TestReflection.Father.pubFatherName
public int Five.TestReflection.Father.pubFatherAge
--測(cè)試getDeclaredField
private java.lang.String Five.TestReflection.Son.priSonName
private int Five.TestReflection.Son.priSonAge
public java.lang.String Five.TestReflection.Son.pubSonName
public int Five.TestReflection.Son.pubSonAge
*/

Field對(duì)象方法

get(Object obj):返回的 Field表示字段的值,指定對(duì)象上

set(Object obj, Object value):設(shè)置域?yàn)榇淼倪@ Field對(duì)象指定對(duì)象上的參數(shù)指定的新價(jià)值

setAccessible():忽略訪問(wèn)修飾符的安全檢查,也稱(chēng)為暴力反射(如果需要get或者set使用private修飾的變量,則需要使用該方法),用于調(diào)試,持久存儲(chǔ),相似機(jī)制。

// 超類(lèi)
public class Father {
    // 成員變量
    private String priFatherName;
    private int priFatherAge;
    public String pubFatherName;
    public int pubFatherAge;
}

// 子類(lèi)
public class Son extends Father {
    // 成員變量
    private String priSonName;
    private int priSonAge;
    public String pubSonName;
    public int pubSonAge;
}
// 測(cè)試類(lèi)
package Five.TestReflection;

import java.lang.reflect.Field;

public class TestField {
    public static void main(String[] args) throws Exception {
        /*
        get和set方法
         */
        Son son = new Son();
        // get,public
        System.out.println("--測(cè)試get方法,使用getField,作用于public修飾對(duì)象");
        Field field3 = Son.class.getField("pubSonName");
        Object value3 = field3.get(son);
        System.out.println(value3);
        // get,private
        System.out.println("--測(cè)試get方法,使用getField,作用于private修飾對(duì)象");
            // 由于getField只能作用于public修飾的成員,因此無(wú)法訪問(wèn)
            // Field field4 = Son.class.getField("priSonName");
            // field4.setAccessible(true);
            // Object value4 = field4.get(son);
            // System.out.println(value4);
                     System.out.println("失敗");
        // get,private
        System.out.println("--測(cè)試get方法,使用getDeclaredField,作用于private修飾對(duì)象");
        Field field5 = Son.class.getDeclaredField("priSonName");
        // 獲取前需要忽略訪問(wèn)的安全檢查
        field5.setAccessible(true);
        Object value5 = field5.get(son);
        System.out.println(value5);
        // set,public
        System.out.println("--測(cè)試set方法,使用getField,作用于public修飾對(duì)象");
        Field field6 = Son.class.getField("pubSonName");
        field6.set(son, "Toyz");
        Object value6 = field6.get(son);
        System.out.println(value6);
        // set,private
        System.out.println("--測(cè)試set方法,使用getDeclaredField,作用于private修飾對(duì)象");
        Field field7 = Son.class.getDeclaredField("priSonName");
            // 獲取前需要忽略訪問(wèn)的安全檢查
            field7.setAccessible(true);
        Object value7 = field7.get(son);
        System.out.println("修改前,priSonName:"+value7);
        field7.set(son, "QQ");
        value7 = field7.get(son);
        System.out.println("修改前,priSonName:"+value7);

    }
}
/* output
--測(cè)試get方法,使用getField,作用于public修飾對(duì)象
null
--測(cè)試get方法,使用getField,作用于private修飾對(duì)象
失敗
--測(cè)試get方法,使用getDeclaredField,作用于private修飾對(duì)象
null
--測(cè)試set方法,使用getField,作用于public修飾對(duì)象
Toyz
--測(cè)試set方法,使用getDeclaredField,作用于private修飾對(duì)象
修改前,priSonName:null
修改前,priSonName:QQ
*/

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

規(guī)則

getConstructor(類(lèi)... parameterTypes):獲取public修飾的指定構(gòu)造方法(不含超類(lèi))

getConstructors():獲取public修飾的所有構(gòu)造方法(不含超類(lèi))

getDeclaredConstructor(類(lèi)... parameterTypes):獲取指定構(gòu)造方法(包括private修飾,暴力反射,不含超類(lèi))

getDeclaredConstructors():獲取所有構(gòu)造方法(包括private修飾,暴力反射,不含超類(lèi))

獲取構(gòu)造方法,無(wú)法獲得超類(lèi),原因是構(gòu)造方法無(wú)法被繼承,因此無(wú)法獲取

// 超類(lèi)
public class Father {
    public Father(String priFatherName , int priFatherAge , String pubFatherName ,
        int pubFatherAge) {
        this.priFatherName = priFatherName;
        this.priFatherAge = priFatherAge;
        this.pubFatherName = pubFatherName;
        this.pubFatherAge = pubFatherAge;
    }

    public Father() { }

    private Father(String priFatherName , int priFatherAge){
        this.priFatherName = priFatherName;
        this.priFatherAge = priFatherAge;
    }
}

// 子類(lèi)
public class Son extends Father {
    public Son(String priSonName , int priSonAge , String pubSonName , int pubSonAge) {
        this.priSonName = priSonName;
        this.priSonAge = priSonAge;
        this.pubSonName = pubSonName;
        this.pubSonAge = pubSonAge;
    }

    public Son(){}

    private Son(String priSonName , int priSonAge){
        this.priSonName = priSonName;
        this.priSonAge = priSonAge;
    }
}
// 測(cè)試類(lèi)
public class TestConstructor {
    public static void main(String[] args) throws Exception {
        /*
        getConstructor和getDeclaredConstructor
         */
        // getConstructor,無(wú)參構(gòu)造器和有參構(gòu)造器
        System.out.println("--測(cè)試getConstructor");
        Constructor constructor1 = Son.class.getConstructor();
        System.out.println("無(wú)參構(gòu)造器:"+constructor1);
        Constructor constructor2 = Son.class.getConstructor(String.class,int.class,String.class,int.class);
        System.out.println("有參構(gòu)造器:"+constructor2);
        // getConstructors
        System.out.println("--測(cè)試getConstructors");
        Constructor[] constructors3 = Son.class.getConstructors();
        for (Constructor c : constructors3) {
            System.out.println(c);
        }
        // getDeclaredConstructor
        System.out.println("--測(cè)試getDeclaredConstructor");
        Constructor constructor4 = Son.class.getDeclaredConstructor(String.class,int.class);
        System.out.println(constructor4);
        // getDeclaredConstructors
        System.out.println("--測(cè)試getDeclaredConstructors");
        Constructor[] constructor5 = Son.class.getDeclaredConstructors();
        for (Constructor c : constructor5){
            System.out.println(c);
        }
    }
}
/* output
--測(cè)試getConstructor
無(wú)參構(gòu)造器:public Five.TestReflection.Son()
有參構(gòu)造器:public Five.TestReflection.Son(java.lang.String,int,java.lang.String,int)
--測(cè)試getConstructors
public Five.TestReflection.Son()
public Five.TestReflection.Son(java.lang.String,int,java.lang.String,int)
--測(cè)試getDeclaredConstructor
private Five.TestReflection.Son(java.lang.String,int)
--測(cè)試getDeclaredConstructors
private Five.TestReflection.Son(java.lang.String,int)
public Five.TestReflection.Son()
public Five.TestReflection.Son(java.lang.String,int,java.lang.String,int)
*/

Constructor對(duì)象方法

newInstance(Object... initargs):利用這 Constructor對(duì)象創(chuàng)建和初始化的構(gòu)造函數(shù)的聲明類(lèi)的一個(gè)新實(shí)例構(gòu)造函數(shù),用指定的初始化參數(shù)。

// 測(cè)試類(lèi)
public class TestConstructor {
    public static void main(String[] args) throws Exception {
        /*
        newInstance(Object... initargs)
         */
        // newInstance(Object... initargs)無(wú)參構(gòu)造器
        System.out.println("--newInstance(Object... initargs) 無(wú)參構(gòu)造器");
        Constructor constructor6 = Son.class.getConstructor();
        System.out.println(constructor6.newInstance());
        // newInstance(Object... initargs)含參構(gòu)造器
        System.out.println("--newInstance(Object... initargs) 含參構(gòu)造器");
        Constructor constructor7 = Son.class.getDeclaredConstructor(String.class,int.class);
        constructor7.setAccessible(true); // 忽略訪問(wèn)的安全檢查
        System.out.println(constructor7.newInstance("Toyz",44));
    }
}
/* output
--newInstance(Object... initargs) 無(wú)參構(gòu)造器
Son{priSonName="null", priSonAge=0, pubSonName="null", pubSonAge=0}
--newInstance(Object... initargs) 含參構(gòu)造器
Son{priSonName="Toyz", priSonAge=44, pubSonName="null", pubSonAge=0}
*/

1.3獲取方法

規(guī)則

getMethod(String name, 類(lèi)... parameterTypes):獲取public修飾的指定方法(含超類(lèi))

getMethods():獲取public修飾的指定方法(含超類(lèi))

getDeclaredMethod(String name, 類(lèi)... parameterTypes):獲取指定方法(包括private修飾,暴力反射,不含超類(lèi))

getDeclaredMethods():獲取所有方法(包括private修飾,暴力反射,不含超類(lèi))

// 超類(lèi)
public class Father {
    // 方法
    public void eat(){
        System.out.println("father eat...");
    }
    public void eat(String food){
        System.out.println("father eat..."+food);
    }
    public void edu(){
        System.out.println("father edu...");
    };
    private void run(){
        System.out.println("father run...");
    }
}

// 子類(lèi)
public class Son extends Father {
    // 方法
    public void eat(){
        System.out.println("son eat...");
    }
    public void eat(String food){
        System.out.println("son eat..."+food);
    }
    private void run(){
        System.out.println("son run...");
    }
}
// 測(cè)試類(lèi)
public class TestMethod {
    public static void main(String[] args) throws Exception {
        /*
        getMethod和getDeclaredMethod
        */
        Son son = new Son();
        // getMethod,空參方法
        System.out.println("--測(cè)試getMethod,空參方法");
        Method method1 = Son.class.getMethod("eat");
        System.out.println(method1);
        // getMethods,所有方法
        System.out.println("--測(cè)試getMethods");
        Method[] method2 = Son.class.getMethods();
        for (Method m : method2) {
            System.out.println(m);
        }
        // getDeclaredMethods,所有方法
        System.out.println("--測(cè)試getDeclaredMethods");
        Method[] method3 = Son.class.getDeclaredMethods();
        for (Method m : method3) {
            System.out.println(m);
        }}}
/* output
--測(cè)試getMethod,空參方法
public void Five.TestReflection.Son.eat()
--測(cè)試getMethods
public java.lang.String Five.TestReflection.Son.toString()
public void Five.TestReflection.Son.eat(java.lang.String)
public void Five.TestReflection.Son.eat()
public void Five.TestReflection.Father.edu()
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
--測(cè)試getDeclaredMethods
private void Five.TestReflection.Son.run()
public java.lang.String Five.TestReflection.Son.toString()
public void Five.TestReflection.Son.eat(java.lang.String)
public void Five.TestReflection.Son.eat()
*/

Method對(duì)象方法

invoke(Object obj, Object... args):第一個(gè)參數(shù)為隱式參數(shù),靜態(tài)方法時(shí)為null。調(diào)用底層的方法,這 方法對(duì)象表示,對(duì)指定對(duì)象的指定參數(shù)。能夠調(diào)用超類(lèi)的方法

// 測(cè)試類(lèi)
public class TestMethod {
    public static void main(String[] args) throws Exception {
        /*
        invoke
        */
        // invoke,含參子類(lèi)public方法
        System.out.println("--測(cè)試invoke,含參子類(lèi)public方法");
        Method method4 = Son.class.getMethod("eat",String.class);
        method4.invoke(son, "Fish");
        // invoke,含參父類(lèi)public方法
        System.out.println("--測(cè)試invoke,含參父類(lèi)public方法");
        Method method5 = Son.class.getMethod("edu");
        method5.invoke(son);
        // invoke,無(wú)參子類(lèi)private方法
        System.out.println("--測(cè)試invoke,無(wú)參子類(lèi)private方法");
        Method method6 = Son.class.getDeclaredMethod("run");
        method6.setAccessible(true);
        method6.invoke(son);
    }
}
/* output
--測(cè)試invoke,含參子類(lèi)public方法
son eat...Fish
--測(cè)試invoke,含參父類(lèi)public方法
father edu...
--測(cè)試invoke,無(wú)參子類(lèi)private方法
son run...
*/

2.Practice(反射)

要求:寫(xiě)一個(gè)“框架”在不改動(dòng)代碼的前提下,通過(guò)配置文件實(shí)現(xiàn)創(chuàng)建任意類(lèi)的對(duì)象,執(zhí)行任意方法

步驟

將需要?jiǎng)?chuàng)建的類(lèi)和執(zhí)行的方法寫(xiě)在配置文件中

在程序中讀取配置文件

使用反射將類(lèi)加載進(jìn)內(nèi)存

創(chuàng)建對(duì)象

執(zhí)行方法

實(shí)現(xiàn)

創(chuàng)建類(lèi)(配置文件需要用到的示范類(lèi))

package Five.TestReflection;
public class Father {
    public Father() { }
    // 方法
    public void eat(){
        System.out.println("father eat...");
    }
}

創(chuàng)建配置文件

className=Five.TestReflection.Father
methodName=eat

讀取并執(zhí)行

package Five.TestReflection;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;

public class TestReflection {
    public static void main(String[] args) throws Exception {
        // 1.加載配置文件
          // 1.1創(chuàng)建pro對(duì)象
          Properties properties = new Properties();
          // 1.2加載配置文件,轉(zhuǎn)換為集合
            // 1.2.1獲取配置文件路徑
            ClassLoader classLoader = TestReflection.class.getClassLoader();
            InputStream is = classLoader.getResourceAsStream("pro.properties");
            properties.load(is);

        // 2.獲取配置文件中定義的數(shù)據(jù)
        String className = properties.getProperty("className");
        String methodName = properties.getProperty("methodName");

        // 3.加載類(lèi)進(jìn)內(nèi)存
        Class cls1 = Class.forName(className);

        // 4.創(chuàng)建對(duì)象-反射
        Object object = cls1.newInstance();

        // 5.執(zhí)行方法-反射
        Method method1 = cls1.getMethod(methodName);
        method1.invoke(object);
    }
}
/* output
father eat...
*/

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/75962.html

相關(guān)文章

  • Spring詳解4.容器內(nèi)幕

    摘要:在這一步里,將配置文件的信息裝入到容器的定義注冊(cè)表中,但此時(shí)還未初始化。注冊(cè)后處理器根據(jù)反射機(jī)制從中找出所有類(lèi)型的,并將它們注冊(cè)到容器后處理器的注冊(cè)表中。是屬性編輯器的注冊(cè)表,主要作用就是注冊(cè)和保存屬性編輯器。 點(diǎn)擊進(jìn)入我的博客 1 Spring容器整體流程 1.1 ApplicationContext內(nèi)部原理 AbstractApplicationContext是Applicati...

    dantezhao 評(píng)論0 收藏0
  • Java學(xué)習(xí)路線總結(jié),搬磚工逆襲Java架構(gòu)師(全網(wǎng)最強(qiáng))

    摘要:哪吒社區(qū)技能樹(shù)打卡打卡貼函數(shù)式接口簡(jiǎn)介領(lǐng)域優(yōu)質(zhì)創(chuàng)作者哪吒公眾號(hào)作者架構(gòu)師奮斗者掃描主頁(yè)左側(cè)二維碼,加入群聊,一起學(xué)習(xí)一起進(jìn)步歡迎點(diǎn)贊收藏留言前情提要無(wú)意間聽(tīng)到領(lǐng)導(dǎo)們的談話,現(xiàn)在公司的現(xiàn)狀是碼農(nóng)太多,但能獨(dú)立帶隊(duì)的人太少,簡(jiǎn)而言之,不缺干 ? 哪吒社區(qū)Java技能樹(shù)打卡?【打卡貼 day2...

    Scorpion 評(píng)論0 收藏0
  • Java三種代理模式:靜態(tài)代理、動(dòng)態(tài)代理和cglib代理

    摘要:動(dòng)態(tài)代理又被稱(chēng)為代理或接口代理。靜態(tài)代理在編譯時(shí)產(chǎn)生字節(jié)碼文件,可以直接使用,效率高。代理無(wú)需實(shí)現(xiàn)接口,通過(guò)生成類(lèi)字節(jié)碼實(shí)現(xiàn)代理,比反射稍快,不存在性能問(wèn)題,但會(huì)繼承目標(biāo)對(duì)象,需要重寫(xiě)方法,所以目標(biāo)對(duì)象不能為類(lèi)。 一、代理模式介紹 代理模式是一種設(shè)計(jì)模式,提供了對(duì)目標(biāo)對(duì)象額外的訪問(wèn)方式,即通過(guò)代理對(duì)象訪問(wèn)目標(biāo)對(duì)象,這樣可以在不修改原目標(biāo)對(duì)象的前提下,提供額外的功能操作,擴(kuò)展目標(biāo)對(duì)象的功...

    Kaede 評(píng)論0 收藏0
  • Java基礎(chǔ)02-自定義注解詳解

    摘要:注解概念注解也被成為元數(shù)據(jù)為我們?cè)诖a中添加信息提供了一種形式化的方式,使我們可以在稍后的某個(gè)時(shí)刻更容易的使用這些數(shù)據(jù)。 注解 概念 注解(也被成為元數(shù)據(jù))為我們?cè)诖a中添加信息提供了一種形式化的方式,使我們可以在稍后的某個(gè)時(shí)刻更容易的使用這些數(shù)據(jù)。 注解是 Java 5 所引入的眾多語(yǔ)言變化之一: 注解使得我們可以以編譯器驗(yàn)證的格式存儲(chǔ)程序的額外信息 注解可以生成描述符文件,甚至是...

    andong777 評(píng)論0 收藏0
  • 大數(shù)據(jù)入門(mén)指南(GitHub開(kāi)源項(xiàng)目)

    摘要:項(xiàng)目地址前言大數(shù)據(jù)技術(shù)棧思維導(dǎo)圖大數(shù)據(jù)常用軟件安裝指南一分布式文件存儲(chǔ)系統(tǒng)分布式計(jì)算框架集群資源管理器單機(jī)偽集群環(huán)境搭建集群環(huán)境搭建常用命令的使用基于搭建高可用集群二簡(jiǎn)介及核心概念環(huán)境下的安裝部署和命令行的基本使用常用操作分區(qū)表和分桶表視圖 項(xiàng)目GitHub地址:https://github.com/heibaiying... 前 言 大數(shù)據(jù)技術(shù)棧思維導(dǎo)圖 大數(shù)據(jù)常用軟件安裝指...

    guyan0319 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<