反射
1、定義
反射就是程序運行時來獲取到某個類或者某個對象的更多的詳細信息(包括但不限於)類包含了哪些屬性,以及屬性的名字,參數和訪問權限,類包含了哪些方法,以及構造方法的名字和參數,類的構造方法以及構造方法的參數。
2、用途
反射就是讓我們在程序運行時獲取一些信息 。是一種雙刃劍,不到萬不得已,不要使用反射
3、反射相關的類
1)Class類:代表類的實體,在運行的Java應用程序中表示類和接口
2)Field類:代表類的成員變量/類的屬性
3)Method類:代表類的方法
4)Constructor類:代表類的構造方法
4.反射的使用
1)獲得Class對象的三種方式
class Animal{
public void eat(String food){
}
}
class Cat extends Animal{
private String name;
public Cat() {
name="小貓";
}
public Cat(String name){
this.name=name;
}
@Override
public void eat(String food){
System.out.println(this.name+"正在喫"+food);
}
}
class Bird extends Animal{
private String name;
public Bird(){
name="小鳥";
}
public Bird(String name){
this.name=name;
}
@Override
public void eat(String food){
System.out.println(this.name+" 正在喫 "+food);
}
}
第一種,使用 Class.forName(“類的全路徑名”); 靜態方法。
前提:已明確類的全路徑名(包名+類名)
//catClass就是Cat類的圖紙,裏頭描述了Cat類的內部構造
Class catClass=Class.forName("hashTable.Cat");
第二種,使用類對象的 getClass() 方法
Cat cat=new Cat("小紅");
Class catClass2=cat.getClass();
第三種,使用 .class 方法。
說明:僅適合在編譯前就已經明確要操作的 Class
Class catClass3=Cat.class;
得到的類對象,在內存中只有一份,不管通過哪種方式獲取到的類對象,本質上只有一份,因此上面三種方式得到的對象都是同一個
2)通過類對象來創建實例
第一種:代碼裏確定要創建哪個類的實例
// 平時創建實例都是通過new的方式
// catClass表示Cat類的類對象,也就是Cat類的圖紙
// newInstance創建對應的實例
Class catClass=Class.forName("hashTable.Cat");
Cat cat= (Cat) catClass.newInstance();
cat.eat("🐟");
第二種:鍵盤輸入確定自己要創建哪個類的實例
Scanner sc=new Scanner(System.in);
String className=sc.next();
System.out.println("您要創建的實例爲:"+className);
Class animal=Class.forName(className);
Animal animal1=(Animal)animal.newInstance();
animal1.eat("🐟");
3)通過反射來修改屬性(可修改private的屬性)
```java
Class catClass=Class.forName("hashTable.Cat");
// //Cat類中包含name屬性,private的屬性
// //catClass是整個類的圖紙,此處想查看圖紙的局部變量
// //通過getDeclaredField能得到局部信息,通過Field對象來表示
Field field=catClass.getDeclaredField("name");
field.setAccessible(true);//這行代碼加上之後就可以訪問private的屬性
//
Cat cat=new Cat();
// //拿着圖紙中的局部信息,拆開cat對象,看看裏面是啥
// //獲取名字之後,還可以修改
field.set(cat,"小喵");
String name= (String) field.get(cat); //相當於cat.name
System.out.println(name);
``
4)通過反射獲取到類中的方法
Class catClass=Class.forName("hashTable.Cat");
// //根據catClass這個圖紙,找到C類中的eat方法
// //獲取到只有一個參數類型爲String的eat方法
Method method=catClass.getMethod("eat",String.class);
Cat cat=new Cat();
method.invoke(cat,"貓糧");
5)獲取構造方法,藉助構造方法來實例化1對象
Class catClass=Class.forName("hashTable.Cat");
//獲取到Cat類中,只有一個參數且類型爲String的構造方法
Constructor constructor=catClass.getConstructor(String.class);
Cat cat= (Cat) constructor.newInstance("小黑");
cat.eat("🐟");
枚舉
用來表示一些可以窮舉出來的概念
enum Sex{
//這些內容的類型不是int,就是Sex類型
MALE,
FEMALE,
OTHER,
}
後面就可以使用Sex.MALE這樣的方式來進行使用了,它們是Sex類型,不參與算術運算
lambda表達式
1、lambda是一個匿名方法,但是在java中,lambda表達式具體的實現方式是通過函數式接口的對象來實現的
2、基本語法
3、實現
ArrayList<Integer> arrayList=new ArrayList<>();
arrayList.add(9);
arrayList.add(5);
arrayList.add(2);
arrayList.add(7);
//sort默認是升序排序,要想讓sort能降序排序,就要給sort的第二個參數指定一個比較器對象
//1、lambda中參數類型可以省略
//2、如果方法體中只有一行代碼,那{ }和return也能省略
Collections.sort(arrayList, (Integer o1,Integer o2) -> {
return o2-o1;
});