成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

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

soasme / 3509人閱讀

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

五.繼承

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

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

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

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

5.1 類、超類和子類 5.1.2 覆蓋方法

規(guī)則

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

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

覆蓋是方法簽名相同

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

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

圖解

5.1.7 阻止繼承:final類和方法

規(guī)則

類用final修飾后,無法被繼承,其中的方法也自動用final修飾。域不包括

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

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

注意

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

5.2 Object:所有類的超類

注意:只有基本類型不是對象

5.2.1 equals

特點(diǎn)

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

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

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

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

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

等號(==)

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

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

equals

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

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

合理的equals重寫邏輯

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

判斷是否引用同一對象

判斷是否為空

判斷是否屬于同一類

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

域的比較

5.2.3 hashCode方法

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

注意

字符串和基本數(shù)據(jù)類型的包裝類創(chuàng)建的對象存在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方法,以便用戶可以將對象插入到散列表中。如果重新定義,會出現(xiàn)equals相等,hashCode不等——考點(diǎn)

5.2.4 toString方法

用途:返回表示對象值的字符串

注意

toString方法常見的原因:當(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
*/

建議重寫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方法

用途:返回包含對象信息的類對象

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ù)只可以代表類,不能代表個別對象

1.ArrayList

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

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

規(guī)則

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

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

使用trimToSize將清除多余的存儲空間

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

注意

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

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

5.4 對象包裝器和自動裝箱 1.自動裝箱

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

// 裝箱
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類型
2.當(dāng)使用.add()方法添加時,被添加的類型為基本類型int
3.因此將自動變換為 list.add(Integer.valueOf(5))
*/

注意

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

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

public class TestAutoBoxing {
    public static void main(String[] args) {
                // 使用包裝類
        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
*/

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

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

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

2.自動拆箱

拆箱 定義:將包裝類數(shù)據(jù)拆成基本類型數(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類型
2.當(dāng)使用.get()方法獲取時,獲得的值類型為Integer
3.因此將自動變換為 int intType = list.get(0).intValue();
*/

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

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

格式

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

// 同時接收多個參數(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對象的數(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 枚舉類

格式

enum EnumName{
    MAX,MIN,DEDIUM;
}

注意

枚舉類中是實(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) {
        // 在同一個類中,因此可以訪問私有的成員變量name
        String name = Size.MAX.name;
        System.out.println(name);
    }
}

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

反射 定義:支持分析類的能力的程序

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

原理圖

獲取Class對象的三種方式

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

多用于配置文件

類名.class:在第二階段,通過類名的class屬性

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

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

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

public class TestReflectionClass {
    public static void main(String[] args) throws Exception {
        /*
        Class對象獲取的三種方式
        1.通過Class.forclass("全類名")獲取
        2.通過類名.class()獲取
        3.通過對象.getClass()方法
        */
        // 1.通過Class.forclass("全類名")獲取
        Class cls1 = Class.forName("Five.TestReflection.Person");
        System.out.println(cls1);
        // 2.通過類名.class()獲取
        Class cls2 = Person.class;
        System.out.println(cls2);
        // 3.通過對象.getClass()方法
        Person p = new Person();
        Class cls3 = p.getClass();
        System.out.println(cls3);
        // 4.比較三個class引用所指向的是否為同一個Class對象
        System.out.println("比較三個class引用所指向的是否為同一個Class對象");
        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
比較三個class引用所指向的是否為同一個Class對象
cls1 == cls2:true
cls1 == cls2:true
*/

注意

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

用途

在運(yùn)行時分析類的能力

在運(yùn)行時操作對象

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

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

5.7.1 Class類 1.Class對象中的功能
1.1獲取成員變量值

規(guī)則

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

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

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

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

注意

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

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

// 子類
public class Son extends Father {
    // 成員變量
    private String priSonName;
    private int priSonAge;
    public String pubSonName;
    public int pubSonAge;
}
// 測試類
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("--測試getField");
        Field[] field1 = Son.class.getFields();
        for (Field f : field1) {
            System.out.println(f);
        }
        // getDeclaredField
        System.out.println("--測試getDeclaredField");
        Field[] field2 = Son.class.getDeclaredFields();
        for (Field f : field2) {
            System.out.println(f);
        }}}
/* output
--測試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
--測試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對象方法

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

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

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

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

// 子類
public class Son extends Father {
    // 成員變量
    private String priSonName;
    private int priSonAge;
    public String pubSonName;
    public int pubSonAge;
}
// 測試類
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("--測試get方法,使用getField,作用于public修飾對象");
        Field field3 = Son.class.getField("pubSonName");
        Object value3 = field3.get(son);
        System.out.println(value3);
        // get,private
        System.out.println("--測試get方法,使用getField,作用于private修飾對象");
            // 由于getField只能作用于public修飾的成員,因此無法訪問
            // 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("--測試get方法,使用getDeclaredField,作用于private修飾對象");
        Field field5 = Son.class.getDeclaredField("priSonName");
        // 獲取前需要忽略訪問的安全檢查
        field5.setAccessible(true);
        Object value5 = field5.get(son);
        System.out.println(value5);
        // set,public
        System.out.println("--測試set方法,使用getField,作用于public修飾對象");
        Field field6 = Son.class.getField("pubSonName");
        field6.set(son, "Toyz");
        Object value6 = field6.get(son);
        System.out.println(value6);
        // set,private
        System.out.println("--測試set方法,使用getDeclaredField,作用于private修飾對象");
        Field field7 = Son.class.getDeclaredField("priSonName");
            // 獲取前需要忽略訪問的安全檢查
            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
--測試get方法,使用getField,作用于public修飾對象
null
--測試get方法,使用getField,作用于private修飾對象
失敗
--測試get方法,使用getDeclaredField,作用于private修飾對象
null
--測試set方法,使用getField,作用于public修飾對象
Toyz
--測試set方法,使用getDeclaredField,作用于private修飾對象
修改前,priSonName:null
修改前,priSonName:QQ
*/

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

規(guī)則

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

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

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

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

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

// 超類
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;
    }
}

// 子類
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;
    }
}
// 測試類
public class TestConstructor {
    public static void main(String[] args) throws Exception {
        /*
        getConstructor和getDeclaredConstructor
         */
        // getConstructor,無參構(gòu)造器和有參構(gòu)造器
        System.out.println("--測試getConstructor");
        Constructor constructor1 = Son.class.getConstructor();
        System.out.println("無參構(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("--測試getConstructors");
        Constructor[] constructors3 = Son.class.getConstructors();
        for (Constructor c : constructors3) {
            System.out.println(c);
        }
        // getDeclaredConstructor
        System.out.println("--測試getDeclaredConstructor");
        Constructor constructor4 = Son.class.getDeclaredConstructor(String.class,int.class);
        System.out.println(constructor4);
        // getDeclaredConstructors
        System.out.println("--測試getDeclaredConstructors");
        Constructor[] constructor5 = Son.class.getDeclaredConstructors();
        for (Constructor c : constructor5){
            System.out.println(c);
        }
    }
}
/* output
--測試getConstructor
無參構(gòu)造器:public Five.TestReflection.Son()
有參構(gòu)造器:public Five.TestReflection.Son(java.lang.String,int,java.lang.String,int)
--測試getConstructors
public Five.TestReflection.Son()
public Five.TestReflection.Son(java.lang.String,int,java.lang.String,int)
--測試getDeclaredConstructor
private Five.TestReflection.Son(java.lang.String,int)
--測試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對象方法

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

// 測試類
public class TestConstructor {
    public static void main(String[] args) throws Exception {
        /*
        newInstance(Object... initargs)
         */
        // newInstance(Object... initargs)無參構(gòu)造器
        System.out.println("--newInstance(Object... initargs) 無參構(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); // 忽略訪問的安全檢查
        System.out.println(constructor7.newInstance("Toyz",44));
    }
}
/* output
--newInstance(Object... initargs) 無參構(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, 類... parameterTypes):獲取public修飾的指定方法(含超類)

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

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

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

// 超類
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...");
    }
}

// 子類
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...");
    }
}
// 測試類
public class TestMethod {
    public static void main(String[] args) throws Exception {
        /*
        getMethod和getDeclaredMethod
        */
        Son son = new Son();
        // getMethod,空參方法
        System.out.println("--測試getMethod,空參方法");
        Method method1 = Son.class.getMethod("eat");
        System.out.println(method1);
        // getMethods,所有方法
        System.out.println("--測試getMethods");
        Method[] method2 = Son.class.getMethods();
        for (Method m : method2) {
            System.out.println(m);
        }
        // getDeclaredMethods,所有方法
        System.out.println("--測試getDeclaredMethods");
        Method[] method3 = Son.class.getDeclaredMethods();
        for (Method m : method3) {
            System.out.println(m);
        }}}
/* output
--測試getMethod,空參方法
public void Five.TestReflection.Son.eat()
--測試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()
--測試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對象方法

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

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

2.Practice(反射)

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

步驟

將需要創(chuàng)建的類和執(zhí)行的方法寫在配置文件中

在程序中讀取配置文件

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

創(chuàng)建對象

執(zhí)行方法

實(shí)現(xiàn)

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

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對象
          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.加載類進(jìn)內(nèi)存
        Class cls1 = Class.forName(className);

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

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

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

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/75962.html

相關(guān)文章

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

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

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

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

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

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

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

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

    andong777 評論0 收藏0
  • 大數(shù)據(jù)入門指南(GitHub開源項(xiàng)目)

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

    guyan0319 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<