成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java語(yǔ)言——反射、枚舉以及l(fā)ambda表達(dá)式

開發(fā) 前端
在日常的第三方應(yīng)用開發(fā)過程中,經(jīng)常會(huì)遇到某個(gè)類的某個(gè)成員變量、方法或是屬性是私有的或是只對(duì)系統(tǒng)應(yīng)用開放,這時(shí)候就可以利用 Java的反射機(jī)制 來(lái)獲取所需的私有成員或是方法 。

一.反射

1.1 反射的基本情況

定義:Java在 運(yùn)行 狀態(tài)時(shí),對(duì)于任意一個(gè)類,都能知道這個(gè)類的所有屬性和方法。

這種動(dòng)態(tài)獲取信息以及動(dòng)態(tài)調(diào)用對(duì)象方法的功能稱為java語(yǔ)言的反射(reflection)機(jī)制

用途:

1.在日常的第三方應(yīng)用開發(fā)過程中,經(jīng)常會(huì)遇到某個(gè)類的某個(gè)成員變量、方法或是屬性是私有的或是只對(duì)系統(tǒng)應(yīng)用開放,這時(shí)候就可以利用 Java的反射機(jī)制 來(lái)獲取所需的私有成員或是方法 。

2. 反射最重要的用途就是開發(fā)各種通用框架,比如在spring中,我們將所有的類Bean交給spring容器管理,無(wú)論是XML配置Bean還是注解配置,當(dāng)我們從容器中獲取Bean來(lái)依賴注入時(shí),容器會(huì)讀取配置,而配置中給的就是類的信息,spring根據(jù)這些信息,需要?jiǎng)?chuàng)建那些Bean,spring就動(dòng)態(tài)的創(chuàng)建這些類。

1.2 反射中最重要的類

在講解這些類之前,我們需要先構(gòu)建一個(gè)類,方便進(jìn)行反射的操作:

class Student{
//私有屬性name
    private String name = "tq02";
//公有屬性age
    public int age = 22;
//不帶參數(shù)的構(gòu)造方法
    public Student(){
    System.out.println("Student()");
    }
    private Student(String name,int age) {
    this.name = name;
    this.age = age;
    System.out.println("Student(String,name)");
    }
    
private void eat(){
    System.out.println("i am eat");
}
public void sleep(){
    System.out.println("i am pig");
}
private void function(String str) {
    System.out.println(str);
} 
 
@Override
public String toString() {
    return "Student{" +
    "name='" + name + '\'' +
    ", age=" + age +
    '}';
}
}

注:1.反射私有的構(gòu)造方法、屬性、方法時(shí),Java具有安全性,因此我們需要使用.setAccessible("boolean");

2.使用Class類、Field、Constructor類時(shí),需要處理異常。

1.2.1 Class類

在反射之前,第一步就是先拿到當(dāng)前需要反射的類的Class對(duì)象,然后通過Class對(duì)象的核心方法,達(dá)到反射的目的,即:在運(yùn)行狀態(tài)中,對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象, 都能夠調(diào)用它的任意方法和屬性,既然能拿到,我們就可以修改部分類型信息。

使用Class獲取 類 的三種方法:

第一種:使用Class.forName("類的全路徑名“”); //靜態(tài)方法

第二種:使用.class方法。

第三種:使用類對(duì)象的getClass()方法;

注:無(wú)論哪種方法獲取,其實(shí)獲取的都是同一個(gè)類。

代碼實(shí)例 :

public class TestDemo {
public static void main(String[] args) {
//1.通過getClass獲取Class對(duì)象
    Student s1 = new Student();
    Class c1 = s1.getClass();
 
//2.直接通過 類名.class 的方式得到,該方法最為安全可靠,程序性能更高
//這說(shuō)明任何一個(gè)類都有一個(gè)隱含的靜態(tài)成員變量 class
    Class c2 = Student.class;
 
//3、通過 Class 對(duì)象的 forName() 靜態(tài)方法來(lái)獲取,用的最多,
//但可能拋出 ClassNotFoundException 異常
    Class c3 = null;
    try {
//注意這里是類的全路徑,如果有包需要加包的路徑
    c3 = Class.forName("Student");
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    } 
 
//一個(gè)類在 JVM 中只會(huì)有一個(gè) Class 實(shí)例,即我們對(duì)上面獲取的
//c1,c2,c3進(jìn)行 equals 比較,發(fā)現(xiàn)都是true
System.out.println(c1.equals(c2));
System.out.println(c1.equals(c3));
System.out.println(c2.equals(c3));
}

1.2.2 Field類

作用:可對(duì)類中屬性進(jìn)行操作

public static void reflectPrivateField() {
  try {
            Class<?> classStudent = Class.forName("Student");
                                                     //獲取name成員變量
            Field field = classStudent.getDeclaredField("name");
            field.setAccessible(true);
            Student student= (Student)classStudent.newInstance();
//修改成員變量,將student中的name值改成"小明";
            field.set(student, "小明");
            String name = (String) field.get(student);
            System.out.println("反射私有屬性修改了name:" + name);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
}

1.2.3 Constructor類

作用:對(duì)構(gòu)造方法進(jìn)行操作

代碼實(shí)例:

//反射構(gòu)造方法
    public static void reflect() {
       try {
           Class<?> c1 = Class.forName("Student");
           Constructor<?> c2= c1.getDeclaredConstructor(String.class,int.class);
           c2.setAccessible(true);
 
           c2.newInstance("湯琦",22);
       }catch(Exception ex)
       {
           ex.printStackTrace();
       }
    }

1.2.4 Method類

作用:對(duì)類中方法進(jìn)行操作

實(shí)例代碼:

public static void reflectPrivateMethod() {
        try {
            Class<?> c1 = Class.forName("Student");
            Method m1=c1.getDeclaredMethod("function", String.class);
            m1.setAccessible(true);
 
            Student fw=(Student) c1.newInstance();
            m1.invoke(fw,"給私有的function函數(shù)傳的參數(shù)");
 
        }catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }

1.3 反射優(yōu)缺點(diǎn)

優(yōu)點(diǎn): 1. 對(duì)于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì) 于任意一個(gè)對(duì)象,都能夠調(diào)用它的任意一個(gè)方法

2. 增加程序的靈活性和擴(kuò)展性,降低耦合性,提高自適應(yīng)能力

3. 反射已經(jīng)運(yùn)用在了很多流行框架如:Struts、Hibernate、Spring 等等。

缺點(diǎn): 1. 使用反射會(huì)有效率問題。會(huì)導(dǎo)致程序效率降低。

2. 反射技術(shù)繞過了源代碼的技術(shù),因而會(huì)帶來(lái)維護(hù)問題。反射代碼比相應(yīng)的直接代碼更復(fù)雜

二.枚舉

2.1 概念

在Java中,可以說(shuō)是一個(gè)集合,從下標(biāo)0開始的集合。注:枚舉是jdk1.5以后引用的。

使用格式: public enum 類名{

常量1、常量2、常量3;

}

就是將class換成了enum

代碼實(shí)例:

public enum TestEnum {
    RED,BLACK,GREEN,WHITE;//相當(dāng)于集合,第一個(gè)常量下標(biāo)值為0,第二個(gè)常量下標(biāo)值為1......
    public static void main(String[] args) {
         TestEnum testEnum2 = TestEnum.BLACK;
         switch (testEnum2) {
         case RED: System.out.println("red"); break;
         case BLACK:System.out.println("black");break;
         case WHITE:System.out.println("WHITE");break;
         case GREEN:System.out.println("black");break;
         default:break;
}
}

2.2 枚舉(enum)類方法

2.3 枚舉的構(gòu)造

枚舉的構(gòu)造方法默認(rèn)是私有的。

public enum TestEnum {
    RED("red",1),BLACK("black",2),WHITE("white",3),GREEN("green",4);
    private String name;
    private int key;
/**
* 1、當(dāng)枚舉對(duì)象有參數(shù)后,需要提供相應(yīng)的構(gòu)造函數(shù)
* 2、枚舉的構(gòu)造函數(shù)默認(rèn)是私有的 這個(gè)一定要記住
* @param name
* @param key
*/
    private TestEnum (String name,int key) {
        this.name = name;
        this.key = key;
    }
    public static TestEnum getEnumKey (int key) {
        for (TestEnum t: TestEnum.values()) {
        if(t.key == key) {
        return t;
        }
    } 
    return null;
}
    public static void main(String[] args) {
        System.out.println(getEnumKey(2));
    }
}

注:自己寫的枚舉類,默認(rèn)繼承與enum這個(gè)類的。

三.Lambda表達(dá)式

3.1 Lambda介紹

Lambda本質(zhì)是匿名函數(shù),基于數(shù)學(xué)中的λ演算得名,也可稱為閉包(Closure)

語(yǔ)法格式:(parameters)->expression 或 (parameters)->{ statements;}

parameters:類似方法中的形參列表,這里的參數(shù)是函數(shù)式接口里的參數(shù)。這里的參數(shù)類型可以明確的聲明也可不聲明而由JVM隱含的推斷。另外當(dāng)只有一個(gè)推斷類型時(shí)可以省略掉圓括號(hào)。

->:可理解為“被用于”的意思

方法體:可以是表達(dá)式也可以代碼塊,是函數(shù)式接口里方法的實(shí)現(xiàn)。代碼塊可返回一個(gè)值或者什么都不反回,這里的代碼塊塊等同于方法的方法體。如果是表達(dá)式,也可以返回一個(gè)值或者什么都不反回。

常見表達(dá)式:

// 1. 不需要參數(shù),返回值為 2
() -> 2
// 2. 接收一個(gè)參數(shù)(數(shù)字類型),返回其2倍的值
x -> 2 * x
// 3. 接受2個(gè)參數(shù)(數(shù)字),并返回他們的和
(x, y) -> x + y
// 4. 接收2個(gè)int型整數(shù),返回他們的乘積
(int x, int y) -> x * y
// 5. 接受一個(gè) string 對(duì)象,并在控制臺(tái)打印,不返回任何值(看起來(lái)像是返回void)
(String s) -> System.out.print(s)

3.2 函數(shù)式接口

定義:該接口有且只有一個(gè) 抽象方法

注:如果某接口含有@FunctionalInterface 注解,那么編譯器就會(huì)按照函數(shù)式接口的定義來(lái)要求該接口,這樣如果有兩個(gè)抽象方法,程序編譯就會(huì)報(bào)錯(cuò)的。

代碼實(shí)例:

@FunctionalInterface
interface NoParameterNoReturn {
	//注意:只能有一個(gè)方法
	void test();
}

3.3 使用lambda表達(dá)式

先建立幾個(gè)接口:

//無(wú)返回值無(wú)參數(shù)
@FunctionalInterface
interface NoParameterNoReturn {
void test();
} 
//無(wú)返回值一個(gè)參數(shù)
@FunctionalInterface
interface OneParameterNoReturn {
void test(int a);
} 
//無(wú)返回值多個(gè)參數(shù)
@FunctionalInterface
interface MoreParameterNoReturn {
void test(int a,int b);
} 
//有返回值無(wú)參數(shù)
@FunctionalInterface
interface NoParameterReturn {
int test();
} 
//有返回值一個(gè)參數(shù)
@FunctionalInterface
interface OneParameterReturn {
int test(int a);
} 
//有返回值多參數(shù)
@FunctionalInterface
interface MoreParameterReturn {
int test(int a,int b);
}

Lambda就是匿名內(nèi)部類的簡(jiǎn)化,實(shí)際上是創(chuàng)建了一個(gè)類,實(shí)現(xiàn)了接口,重寫了接口的方法 。

3.3.1 不使用Lambda表達(dá)式調(diào)用

public class TestDemo {
public static void main(String[] args) {
//接口使用匿名內(nèi)部類
    NoParameterNoReturn noParameterNoReturn = new NoParameterNoReturn(){
    @Override
    public void test() {
    System.out.println("hello");
    }
    };
noParameterNoReturn.test();
}

3.3.2 使用Lambda表達(dá)式

public class TestDemo {
  public static void main(String[] args) {
    NoParameterNoReturn noParameterNoReturn = ()->{
    System.out.println("無(wú)參數(shù)無(wú)返回值");
};
noParameterNoReturn.test();
    OneParameterNoReturn oneParameterNoReturn = (int a)->{
    System.out.println("一個(gè)參數(shù)無(wú)返回值:"+ a);
};
oneParameterNoReturn.test(10);
 
    MoreParameterNoReturn moreParameterNoReturn = (int a,int b)->{
    System.out.println("多個(gè)參數(shù)無(wú)返回值:"+a+" "+b);
};
moreParameterNoReturn.test(20,30);
 
    NoParameterReturn noParameterReturn = ()->{
    System.out.println("有返回值無(wú)參數(shù)!");
    return 40;
};
//接收函數(shù)的返回值
int ret = noParameterReturn.test();
System.out.println(ret);
    OneParameterReturn oneParameterReturn = (int a)->{
    System.out.println("有返回值有一個(gè)參數(shù)!");
    return a;
};
ret = oneParameterReturn.test(50);
System.out.println(ret);
 
    MoreParameterReturn moreParameterReturn = (int a,int b)->{
    System.out.println("有返回值多個(gè)參數(shù)!");
    return a+b;
};
ret = moreParameterReturn.test(60,70);
System.out.println(ret);
}
}

3.3.3 二者區(qū)別

代碼實(shí)例:

1. 參數(shù)類型可以省略,如果需要省略,每個(gè)參數(shù)的類型都要省略。

2. 參數(shù)的小括號(hào)里面只有一個(gè)參數(shù),那么小括號(hào)可以省略

3. 如果方法體當(dāng)中只有一句代碼,那么大括號(hào)可以省略

4. 如果方法體中只有一條語(yǔ)句,且是return語(yǔ)句,那么大括號(hào)可以省略,且去掉return關(guān)鍵字。

3.4 變量捕獲

變量捕獲,在匿名內(nèi)部類中也存在,而類似匿名內(nèi)部類的Lambda表達(dá)式,自然而然也存在。

3.4.1 匿名內(nèi)部類的變量捕獲

外,已經(jīng)定義了a的值,因此匿名內(nèi)部類直接捕獲了外部的a變量。

3.4.2 Lambda變量捕獲

如上圖,使用直接捕獲了外部的a變量。

注:無(wú)論是匿名內(nèi)部類的變量捕獲還是Lambda變量捕獲,方法體里,不可修改外部變量的值。

總結(jié)

反射、枚舉以及Lambda表達(dá)式很少使用,算是偏僻的知識(shí)點(diǎn),因此不要求掌握,只要求熟悉。

責(zé)任編輯:武曉燕 來(lái)源: 今日頭條
相關(guān)推薦

2012-06-26 10:03:58

JavaJava 8lambda

2013-01-05 02:19:50

JavaLambda表達(dá)式JVM

2009-09-09 13:01:33

LINQ Lambda

2009-09-15 15:18:00

Linq Lambda

2022-12-05 09:31:51

接口lambda表達(dá)式

2009-09-11 09:48:27

Linq Lambda

2013-04-07 15:44:26

Java8Lambda

2009-08-27 09:44:59

C# Lambda表達(dá)

2009-09-15 17:30:00

Linq Lambda

2009-09-17 09:44:54

Linq Lambda

2009-09-17 10:40:22

Linq Lambda

2013-04-07 10:04:03

Java8Lambda

2024-03-25 13:46:12

C#Lambda編程

2009-08-10 09:41:07

.NET Lambda

2009-09-09 17:14:17

Linq lambda

2013-04-10 10:58:19

LambdaC#

2009-08-27 09:57:50

C# Lambda表達(dá)

2009-08-31 17:11:37

Lambda表達(dá)式

2009-09-17 09:09:50

Lambda表達(dá)式Linq查詢

2009-08-26 16:17:23

C# Lambda表達(dá)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 成人免费视频在线观看 | 午夜精品久久久久久不卡欧美一级 | 亚洲a视频 | 欧美精品一区二区三区在线播放 | 免费一级黄色录像 | 美女爽到呻吟久久久久 | 在线国产一区二区三区 | 色爱综合网 | 国产午夜精品一区二区三区嫩草 | 久久久久久99 | 国产福利视频网站 | 日韩国产在线观看 | 国产在线拍偷自揄拍视频 | 91在线精品视频 | 欧美日韩激情 | 成人免费视频网站在线观看 | 精品视频一二区 | 欧美日韩一区二区视频在线观看 | 免费久久网 | 日韩在线不卡视频 | 亚洲天堂999 | 亚洲欧美日韩精品久久亚洲区 | 91久久久久久久久久久 | 国产精品福利视频 | 91在线视频播放 | 久久久久亚洲精品 | 99免费视频| 在线观看免费av网 | 日本欧美国产 | 国产一区在线免费观看 | 久久99精品久久久久婷婷 | 在线观看成年人视频 | 亚洲欧美国产精品久久 | 色婷婷综合久久久中文字幕 | 奇米在线 | 中文字幕欧美一区二区 | 中文字幕成人 | 日韩中文在线视频 | 中文字幕在线精品 | 亚洲精品中文字幕在线观看 | 四季久久免费一区二区三区四区 |