枚举(enum)是一种特殊的类,用于定义一组常量。枚举类可以包含字段、方法和构造函数,可以实现接口,但不能继承其他类。枚举类的定义和使用非常方便,适用于表示一组固定的常量值。
枚举类的定义
public enum Season {
SPRING,SUMMER,AUTUMN,WINTER;
}
枚举类的特点
1.所有枚举类都是Enum的子类
2.我们可以通过"枚举类名.枚举项名称"去访问指定的枚举项
System.out.println(Season.SUMMER);
3.每一个枚举项其实就是该枚举的一个(匿名)对象, 因此枚举项不能直接访问枚举类里的private成员变量
4.枚举也是一个类,也可以去定义成员变量
5.枚举类的第一行必须是枚举项
6.枚举类可以有构造方法, 但必须是private的(默认的空参构造也是private的)
private Season(String description) {
this.description = description;
}
7.枚举类也可以有抽象方法,但是枚举项必须重写该方法
枚举类的方法
String name()获取枚举项的名称
System.out.println(Season.WINTER.name());
int ordinal() 返回枚举项在枚举类中的索引值(从0开始按顺序)
System.out.println(Season.SUMMER.ordinal());
int compareTo(E o)比较两个枚举项 返回的是索引值的差
int i = Season.WINTER.compareTo(Season.SPRING);
String toString()返回枚举常量的名称
System.out.println(Season.WINTER.toString());
static <T> T valueOf(Class<T> type, String name)
Season spring = Enum.valueOf(Season.class, "SPRING");//这样得到的和Seasom.SPRING一模一样
values()返回所有枚举类对象, 存储在一个数组里
Season[] seasons = Season.values();
类加载器
static ClassLoader getSystemClassLoader
获取系统类加载器ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
InputStream getResourceAsStream(String name)
加载某个资源文件//加载资源文件 InputStream is = systemClassLoader.getResourceAsStream("prop.properties"); Properties prop = new Properties(); prop.load(is); System.out.println(prop);
反射机制
一.概述
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。
利用反射可以无视修饰符获取类里面所有的属性和方法. 先获取配置文件中的信息,动态获取信息并创建对象和调用方法
二.反射-获取class对象
1.通过Class中的静态方法forname("全类名")
Class clazz = Class.forName("com.itheima.myreflect2.Student");
2.通过类的class属性获取
Class<Student> clazz2 = Student.class;
3.通过对象的getClass方法获取class对象
Student s = new Student();
Class clazz3 = s.getClass();
三.反射-获取Constructor对象
Class类中用于获取构造方法的方法
getConstructors
返回一个包含所有public构造方法的数组Constructor[] constructors = clazz.getConstructors();
getDeclaredConstructors()
返回一个所有(包括private)构造方法的数组Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
getConsturctor()
获取类的指定public构造方法,需要在参数内填入需要查找的构造方法的类型Constructor constructor = clazz.getConstructor(String.class, int.class);
getDeclaredConstructor()
获取类的指定构造方法(包含private方法)Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class, int.class);
四.反射-利用Constructor创建对象
constructor.newInstance("张三", 15);
适用于所有构造方法- 通过私有构造方法创建对象前, 需要先绕过 Java 的访问控制机制
//创建Class对象
Class clazz = Student.class;
//得到构造方法
Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class);
declaredConstructor.setAccessible(true);//绕过 Java 的访问控制机制
Student stu =(Student) declaredConstructor.newInstance("张三");
System.out.println(stu);
3.(一种已经过时的方法)通过Class对象直接调用空参构造,并且只能调用空参构造
Student stu1 = (Student) clazz.newInstance();
五.反射-Field对象(获取成员变量)
1.利用Class对象获得Field成员变量数组
clazz.getFields()
clazz.getDeclaredFields
这两个方法的用法和上文中获取Constructor数组的方法一模一样
2.利用Class对象获得单个Field对象
clazz.getField("gender")
获取public的gender成员变量
clazz.getDeclaredField("name")
获取private的name成员变量
3.利用Field对象获取值和赋值
获取值: (String) gender.get(student)
获取student对象的gender变量的值
gender.getModifiers()
获取gender变量的权限(public, private等)修饰符
gender.getName()
获取在Student类中, gender这个成员变量叫什么名字
赋值: name.set(student, "黄乘明");
有两个参数(要修改的对象, 修改后的值)
在访问或修改私有字段的时候也需要先绕过 Java 的访问控制机制
namefield.setAccessible(true);
六:反射-Method对象
1.获取public修饰的Method对象数组(包含父类中的对象)
clazz.getMethods()
2.获取所有Method对象数组(不包含父类中的, 但是private修饰的也能找到)
clazz.getDeclaredFields()
3.获取指定的单一方法
clazz.getMethod
和 clazz.getDeclaredMethod
clazz.getMethod("eat", String.class);//要带上方法名和形参的类型
clazz.getDeclaredMethod("sleep")
4.通过Method方法获取方法的信息:
//获取方法的修饰符
System.out.println(eat.getModifiers());
//获取方法的名字
System.out.println(eat.getName());
//获取方法的形参
Parameter[] parameters = eat.getParameters();
//获取方法抛出的异常数组
Class[] exceptionTypes = eat.getExceptionTypes();
5.利用Method对象运行方法
Class clazz = Student.class;//获取Class对象
Method eat = clazz.getDeclaredMethod("eat", String.class);//获取类中的eat方法
eat.setAccessible(true);//绕过Java访问限制
String invoke = (String) eat.invoke(student, " 汉堡包");//使用Method对象运行方法(对象, 参数)
System.out.println(invoke);//输出运行结果