一、枚举
传统的方式:
?在某些情况下,一个类的对象是有限而且固定的。例如季节类,只能有 4 个对象
?手动实现枚举类:
—private
修饰构造器。
—属性使用 private final
修饰。
—把该类的所有实例都使用 public static
final 来修饰。
练习代码:
1 public class Season {
2
3 //1、因为类的对象是固定的,所以类的属性是常量
4 public final String name;
5 public final String desc;
6
7 //2、因为类的对象是有限个,所以不能在类的外部创建对象,构造器必须私有
8 private Season(String name,String desc){
9 this.name = name;
10 this.desc = desc;
11 }
12
13 //3、在类的内部创建对象,但要在类的外部能够访问到该对象,而且还不能修改。
14 public static final Season SPRING = new Season("春天","春风又绿江南岸");
15 public static final Season SUMMER = new Season("夏天","映日荷花别样红");
16 public static final Season FALL = new Season("秋天","秋水共长天一色");
17 public static final Season WINTER = new Season("冬天","窗寒西岭千秋雪");
18
19 public String getName() {
20 return name;
21 }
22 public String getDesc() {
23 return desc;
24 }
25
26 @Override
27 public String toString() {
28 return "Season [name=" + name + ", desc=" + desc + "]";
29 }
30 }
Season类
1 public class TestSeason {
2
3 public static void main(String[] args) {
4
5 Season SPRING = Season.SPRING;
6 System.out.println(SPRING);
7
8 }
9 }
TestSeason类
现在的方式:
?JDK 1.5 新增的 enum 关键字用于定义枚举类。
?枚举类和普通类的区别:
—使用 enum 定义的枚举类默认继承了
java.lang.Enum 类。
—枚举类的构造器只能使用 private 访问控制符。
—枚举类的所有实例必须在枚举类中显式列出(, 分隔 ; 结尾). 列出的实例系统会自动添加
public static
final 修饰。
—所有的枚举类都提供了一个 values
方法, 该方法可以很方便地遍历所有的枚举值。
?JDK 1.5 中可以在 switch
表达式中使用枚举类的对象作为表达式, case 子句可以直接使用枚举值的名字,
无需添加枚举类作为限定。
?若枚举只有一个成员, 则可以作为一种单子模式的实现方式。
注意枚举类的属性:
?枚举类对象的属性不应允许被改动, 所以应该使用 private final
修饰。
?枚举类使用 private final 修饰的属性应该在构造器中为其赋值。
?若枚举类显式的定义了带参数的构造器, 则在列出枚举值时也必须对应的传入参数。
实现接口的枚举类:
?和普通 Java 类一样枚举类可以实现一个或多个接口。
?若需要每个枚举值在调用实现的接口方法呈现出不同的行为方式,
则可以让每个枚举值分别来实现该方法。
(采用匿名内部类实现方法的重写)
枚举类的方法:
练习代码:
1 public interface DateInfo {
2 public String getDateInfo();
3 }
DateInfo接口
1 public enum Season2 implements DateInfo {
2
3 SPRING("春天","春风又绿江南岸"){
4 @Override
5 public String getDateInfo() {
6 return "2-5";
7 }
8 },
9 SUMMER("夏天","映日荷花别样红"){
10 @Override
11 public String getDateInfo() {
12 return "5-8";
13 }
14 },
15 FALL("秋天","秋水共长天一色"){
16 @Override
17 public String getDateInfo() {
18 return "8-11";
19 }
20 },
21 WINTER("冬天","窗寒西岭千秋雪"){
22 @Override
23 public String getDateInfo() {
24 return "11-2";
25 }
26 },;
27
28 private String name;
29 private String desc;
30
31 private Season2(String name,String desc){
32 this.name = name;
33 this.desc = desc;
34 }
35
36 public String getName() {
37 return name;
38 }
39
40 public String getDesc() {
41 return desc;
42 }
43
44 /* @Override 改为利用匿名内部类重写的方法更酷些
45 public String getDateInfo() {
46 System.out.println(this.toString().equals("SPRING"));
47 return null;
48 } */
49 }
Season2类继承接口DateInfo
1 public class TestSeason {
2
3 public static void main(String[] args) {
4
5 // Season SPRING = Season.SPRING;
6 // System.out.println(SPRING);
7 // System.out.println(Season2.SPRING);
8 for(Season2 s:Season2.values()){
9 // System.out.println(s);
10 // System.out.println(s.toString().equals("SPRING"));
11 System.out.println(s.getDateInfo());
12 }
13
14 String str = "WINTER";
15 Season2 s = Season2.valueOf(Season2.class, str);
16 System.out.println(s.getName()+" "+s.getDesc());
17 }
18 }
TestSeason测试类
二、Annotation(注释)
1、概述:
?从 JDK 5.0 开始, Java 增加了对元数据(MetaData) 的支持, 也就是 Annotation(注释)。
?Annotation 其实就是代码里的特殊标记, 这些标记可以在编译,
类加载, 运行时被读取, 并执行相应的处理.
通过使用 Annotation, 程序员可以在不改变原有逻辑的情况下, 在源文件中嵌入一些补充信息。
?Annotation 可以像修饰符一样被使用, 可用于修饰包,类,
构造器, 方法, 成员变量, 参数, 局部变量的声明,
这些信息被保存在 Annotation 的 “name=value” 对中。
?Annotation 能被用来为程序元素(类, 方法,
成员变量等) 设置元数据。
2、基本的 Annotation:
?使用 Annotation 时要在其前面增加 @ 符号, 并把该 Annotation 当成一个修饰符使用,
用于修饰它支持的程序元素。
?三个基本的 Annotation:
— @Override:
限定重写父类方法, 该注释只能用于方法
— @Deprecated:
用于表示某个程序元素(类, 方法等)已过时
— @SuppressWarnings:
抑制编译器警告.
3、自定义 Annotation:
?定义新的 Annotation 类型使用
@interface 关键字。
?Annotation 的成员变量在 Annotation
定义中以无参数方法的形式来声明. 其方法名和返回值定义了
该成员的名字和类型。
?可以在定义 Annotation 的成员变量时为其指定初始值, 指定成员变量的初始值可使用 default 关键字。
?没有成员定义的 Annotation 称为标记; 包含成员变量的 Annotation 称为元数据 Annotation。
4、提取 Annotation 信息:
?JDK 5.0 在 java.lang.reflect 包下新增了
AnnotatedElement 接口, 该接口代表程序中可以
接受注释的程序元素。
?当一个 Annotation 类型被定义为运行时 Annotation
后, 该注释才是运行时可见, 当 class 文件被载入时
保存在 class 文件中的 Annotation 才会被虚拟机读取。
?程序可以调用 AnnotationElement 对象的如下方法来访问 Annotation 信息。
5、JDK 的元 Annotation:
?JDK 的元 Annotation 用于修饰其他 Annotation 定义
[email protected]: 只能用于修饰一个 Annotation 定义, 用于指定该 Annotation 可以保留多长时间,
@Rentention 包含一个 RetentionPolicy 类型的成员变量, 使用 @Rentention 时必须为该 value
成员变量
指定值:
–RetentionPolicy.CLASS: 编译器将把注释记录在 class 文件中. 当运行 Java
程序时,
JVM 不会保留注释. 这是默认值。
–RetentionPolicy.RUNTIME:编译器将把注释记录在 class 文件中. 当运行
Java 程序时, JVM 会保留注释,
程序可以通过反射获取该注释。
–RetentionPolicy.SOURCE: 编译器直接丢弃这种策略的注释。
?@Target: 用于修饰 Annotation 定义,
用于指定被修饰的 Annotation 能用于修饰哪些程序元素,
@Target 也包含一个名为 value 的成员变量.
[email protected]: 用于指定被该元 Annotation 修饰的 Annotation 类将被 javadoc 工具提取成文档.
[email protected]: 被它修饰的 Annotation 将具有继承性.如果某个类使用了被 @Inherited 修饰的
Annotation,
则其子类将自动具有该注释.
练习例子:
1 import java.lang.annotation.ElementType;
2 import java.lang.annotation.Target;
3
4 /**
5 * 1. 使用 @interface 定义注解
6 * 2. 使用类似于接口方法声明的方式来定义注解的属性: 其中返回值称为属性的类型, 方法名为属性的名称.
7 *
8 */
9 @Target(value={ElementType.METHOD, ElementType.TYPE})
10 public @interface HelloAnnotation {
11
12 public String name() default "atguigu";
13
14 }
@interface与@Target用法
1 public class TestAnnotation {
2
3 @SuppressWarnings("unused")
4 public static void main(String[] args) {
5
6 A a = new A();
7 a.method2();
8
9 String str = "abc";
10 }
11 }
12
13 @HelloAnnotation(name="abc")
14 class A{
15
16 @HelloAnnotation()
17 void method1(){}
18
19 @Deprecated
20 void method2(){}
21
22 }
23
24 class B extends A{
25
26 @Override
27 void method1(){}
28
29 }
TestAnnotation类
复习java第五天(枚举、Annotation(注释) 概述),布布扣,bubuko.com