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类型,不参与算术运算
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;
});