如果我们有一个需求,就是要创建季节(Season)对象,我们会如何完成呢?
最直接的想法就是:
class Season{
private String name;
private String desc;//描述
//构造器
//.get
}
但是,对于这个实现方式,我们并不觉得完美。
因为我们知道,Season对象有如下的特点:
1、季节的值只有固定的四个(spring,summer,autumn,winter)
2、季节是只读的,不需要被修改
但我们上述的代码是一种通解的方式,没有具体满足季节类的两个要求。
为此,我们引入枚举来解决这个问题。
枚举对应英文enumeration,简写为enum
枚举是一组常量的集合。
我们可以将枚举理解为一种特殊的类,里面只包含一组有限的特定对象。
1、自定义类实现枚举
2、使用enum关键字实现枚举
下面我们依次介绍:
这种方式就是利用类的定义来实现枚举类。
应用细节:
1、对于不需要提供setXxx方法,因为枚举对象值通常为只读的。
2、对枚举对象/属性使用final+static共同修饰,实现底层优化。
3、枚举对象名通常使用全部大写,这是按照常量的命名规范来的。
4、枚举对象根据需要,也可以有多个属性。
示例代码如下:
class Season{
private String name;//季节名称
private String description;//季节描述
public String getName(){
return name;
}
public String getDescription(){
return description;
}
private Season(String name, String description){
this.name = name;
this.description = description;
}
public final static Season SPRING = new Season(“春天”, “温暖”);
public final static Season SUMMER = new Season(“夏天”, “炎热”);
public final static Season AUTUMN = new Season(“秋天”, “凉爽”);
public final static Season WINTER = new Season(“冬天”, “寒冷”);
}
//1.将构造器私有化,目的是防止直接new
//2.去掉setXxx方法,防止属性被修改
//3.在Season内部直接创建固定的对象
//4.优化,可以加入final修饰符
小结:
1、构造器私有化
2、本类内部创建一组对象
3、对外暴露对象(通过为对象添加public final static修饰符)
4、可以提供get方法,但不要提供set方法
代码示例如下:
enum Season2{
//在enum枚举类内以下语句:
//public final static Season2 SPRING = new Season2(“春天”, “温暖”);
//可以简化为如下形式:
SPRING(“春天”, “温暖”);
SUMMER(“夏天”, “炎热”);
AUTUMN(“秋天”, “凉爽”);
WINTER(“冬天”, “寒冷”);
private String name;
private String desc;
private Season2(String name, String desc){
this.name = name;
this.desc = desc;
}
public String getName(){
return name;
}
public String getDesc(){
return desc;
}
}
//如果使用了enum来实现枚举类,则:
//1.使用关键字enum来代替class
//2.上面说的语句简化,创建对象的语句可以简化为 常量名(实参列表)
//按照本例为例子来说,可以写为:
//SPRING(“春天”, “温暖”), SUMMER(“夏天”, “炎热”), AUTUMN(“秋天”, ”凉爽”), WINTER(“冬天”, ”寒冷”);
//多个对象用 , 间隔即可
//并且,如果用enum来实现枚举,要求将定义常量对象写在最前面。
1、使用enum关键字开发一个枚举类的时候,默认会继承Enum类,且是一个final类(可以用javap反编译命令来查看,这个指令会讲.class文件反编译回.java文件)
2、刚刚说的语句简化,必须知道调用的是哪个构造器,即下面必须要有对应形式的构造器。如果用无参构造器来创建枚举对象,则是惨烈表和小括号都可以省略。
3、多个枚举对象之间用,间隔,最后用;结尾。
4、枚举对象必须放在枚举类的行首。
5、枚举对象相当于静态对象,不同的引用若指向同一个对象,则地址是一样的。
6、枚举类的对象相当于已经在类定义的时候就写出来了。故调用枚举对象的时候,用枚举类名.对象名来进行调用。
因为使用enum关键字会隐式继承Enum类,这样我们就能够使用Enum类相关的方法。
1、toString:
Enum类已经重写过该方法类,返回的是当前对象名,子类可以重写该方法,用于返回对象的属性信息。
2、name:
返回当前对象名(常量名),子类中不能重写。
3、ordinal:
返回当前对象的位置号,默认从0开始。
4、values:
返回当前枚举类中所有的常量。
5、valueOf:
将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报错!
6、compareTo:
比较两个枚举常量的位置号的次序作差。
补充增强for循环:
int[] nums = {1, 2, 9};
//普通for循环
for(int i = 0; i < nums.length; i++){
System.out.println(nums[i]);
}
//增强for循环
for(int i : nums){
System.out.println(“i=“ + i );
}
//执行流程是,依次从nums数组中取出数据赋值给i,如果取出完毕,则退出for
因为Java的单继承机制,一旦使用enum关键字,枚举类就没办法继承其他类了。不过,枚举类和普通类一样,可以实现接口:
enum 类名 implements 接口1, 接口2{}
枚举类可以配合switch使用,对枚举类内部的常量进行匹配。只需要在swtich()中放入枚举对象,在每个case后直接写上在枚举类中定义的枚举对象即可。
注解(Annotation)也被称为元数据(Metadata),用于修饰解释包、类、方法、属性、构造器、局部变量等数据信息。
和注释一样,注解不影响程序逻辑,但注解可以被编译运行,相当于嵌入在代码中的补充信息。
在JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在JavaEE中注解更为重要,例如用来配置应用程序的任何切面,代替javaEE旧版中所遗留的繁冗代码和XML配置等。
使用注解时要在其前面加@符号,并把该Annotation当成修饰符使用,用于修饰它支持的程序元素。
三个基本的Annotation为:
1、@Override:限定某个方法是重写父类方法,该注解只能适用于方法。
2、@Deprecated:用于表示某个程序元素(类、方法等)已过时。
3、@SuppressWarnings:抑制编译器警告。
只适用于方法。
class Father{
public void fly(){
System.out.println("Father fly...");
}
}
class Son extends Father{
@Override
public void fly(){
System.out.println("Son fly...");
}
}
//注意,@Override放在fly方法上,表示子类方法重写父类的方法,但就算不写这个注解,这里也会重写。写上这个注解的作用是让编译器去检查子类方法是否真的重写父类方法,若没有,则编译器会报错。
直接在你想要使用的元素前一行写上就可以,表示不再推荐使用该元素,但仍然可以使用,只是未来有可能不再支持,便于新旧版本的兼容和过渡。
可以用于类、字段、包、参数等等位置。
当我们不希望看到编译器警告的时候,我们可以写上这个注解。其作用范围就是其下一句那一个代码块(方法/类/语句),假如放在main方法前一行,那作用范围就是main方法。
@SuppressWarnings({"all"})
@SuppressWarnings({"rawtypes", "unchecked"})
在{}内不同的字符串可以指定忽略不同的警告类型,但不用背,直接看IDE左边的黄色提示选择你想要的就好。