10.1.枚舉類的使用: 入門
類的對象只有有限個(gè),確定的
自定義枚舉類
一.枚舉類的使用
1.枚舉類的理解: 類的對象只有有限個(gè),確定的.稱之為枚舉類
2.當(dāng)要定義一組常量時(shí),強(qiáng)烈建議用枚舉類
3.如果枚舉類中只有一個(gè)對象,則可以作為單例模式的實(shí)現(xiàn)方式
// 自定義枚舉類的展現(xiàn)
public class SeasonTest {
public static void main(String[] args) {
// 調(diào)用枚舉類的對象
Season1 spring = Season1.SPRING;
System.out.println(spring);
}
}
// 自定義枚舉類,還是繼承于Object類
class Season {
//1.聲明Season對象的屬性:private final修飾,對象地址不變
private final String seasonName;
private final String seasonDesc;
// 2.私有化構(gòu)造器,并給對象屬性賦值,在構(gòu)造器里賦值每個(gè)對象屬性值可以不一樣
private Season(String seasonName, String seasonDesc){
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
// 3.提供當(dāng)前枚舉類的多個(gè)對象,對象作為常量出現(xiàn),直接定義為用類調(diào): 聲明為 public static final
public static final Season SPRING = new Season("春天", "春暖花開");
public static final Season SUMMER = new Season("夏天", "夏日炎炎");
public static final Season AUTUMN = new Season("秋天", "秋高氣爽");
public static final Season WINTER = new Season("冬天", "冰天雪地");
// 4.訴求1.獲取枚舉類對象的屬性
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
// 5.訴求2.提供重寫的toString()
@Override
public String toString() {
return "Season{" +
"seasonName='" + seasonName + '\'' +
", seasonDesc='" + seasonDesc + '\'' +
'}';
}
}
- 使用enum關(guān)鍵字定義枚舉類
- Enum類的常用方法
說明: 定義的枚舉類默認(rèn)繼承于java.lang.Enum類
public class SeasonTest1 {
public static void main(String[] args) {
Season1 summer = Season1.SUMMER;
System.out.println(summer);
// season1.class表示類的對象
System.out.println(Season1.class.getSuperclass());// java.lang.Enum
// toString(): 獲取枚舉類對象的名字/常量名
System.out.println(summer.toString());
// values(): 生成一個(gè)枚舉類對象常量的數(shù)組,可以看枚舉類狀態(tài)
Season1[] values = Season1.values();
for (int i = 0; i < values.length; i++) {
System.out.println(values[i]);
}
Thread.State[] values1 = Thread.State.values();
for (int i = 0; i < values1.length; i++) {
System.out.println(values1[i]);
}
// valueOf(String objName): 根據(jù)對象名傳入的對象名,判斷是否存是objName對象;找指定名的對象
// 如果沒有objName的枚舉類對象,則拋異常: IllegalArgumentException
Season1 winter = Season1.valueOf("winter");
System.out.println(winter);
}
}
// 使用enum關(guān)鍵字枚舉類
enum Season1 {
// 1.提供(創(chuàng)建)當(dāng)前枚舉類的對象,多個(gè)對象之間用","隔開,末尾對象用";"結(jié)束
SPRING("春天", "春暖花開"),// 括號(hào)中含屬性
SUMMER("夏天", "夏日炎炎"),
AUTUMN("秋天", "秋高氣爽"),
WINTER("冬天", "冰天雪地");
//2.聲明Season對象的屬性:private final修飾,對象地址不變
private final String seasonName;
// 2.私有化構(gòu)造器,并給對象屬性賦值,在構(gòu)造器里賦值每個(gè)對象屬性值可以不一樣
private final String seasonDesc;
private Season1(String seasonName, String seasonDesc){
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
// 4.訴求1.獲取枚舉類對象的屬性
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
// 5.訴求2.提供重寫的toString()
// 已經(jīng)給重寫過了,默認(rèn)打印對象的名字
/*@Override
public String toString() {
return "Season1{" +
"seasonName='" + seasonName + '\'' +
", seasonDesc='" + seasonDesc + '\'' +
'}';
}*/
}
- 使用enum關(guān)鍵字定義的枚舉類實(shí)現(xiàn)接口
情況一: 實(shí)現(xiàn)接口,在enum類中實(shí)現(xiàn)抽象方法
情況二: 讓枚舉類的對象分別實(shí)現(xiàn)接口中的抽象方法,體現(xiàn)每個(gè)枚舉類對象的方法體都不一樣了
public class SeasonTest1 {
public static void main(String[] args) {
Season1 summer = Season1.SUMMER;
System.out.println(summer);
// season1.class表示類的對象
System.out.println(Season1.class.getSuperclass());// java.lang.Enum
// toString(): 獲取枚舉類對象的名字/常量名
System.out.println(summer.toString());
// values(): 生成一個(gè)枚舉類對象常量的數(shù)組,可以看枚舉類狀態(tài)
Season1[] values = Season1.values();
for (int i = 0; i < values.length; i++) {
System.out.println(values[i]);
values[i].show();
}
Thread.State[] values1 = Thread.State.values();
for (int i = 0; i < values1.length; i++) {
System.out.println(values1[i]);
}
// valueOf(String objName): 根據(jù)對象名傳入的對象名,判斷是否存是objName對象;找指定名的對象
// 如果沒有objName的枚舉類對象,則拋異常: IllegalArgumentException
Season1 winter = Season1.valueOf("WINTER");
System.out.println(winter);
winter.show();// 調(diào)用實(shí)現(xiàn)接口的方法
}
}
// 定義一個(gè)接口
interface Info{
void show();// 省略 public abstract
}
// 使用enum關(guān)鍵字枚舉類
enum Season1 implements Info{
// 1.提供(創(chuàng)建)當(dāng)前枚舉類的對象,多個(gè)對象之間用","隔開,末尾對象用";"結(jié)束
// 每個(gè)枚舉類的對象都可以實(shí)現(xiàn)接口的抽象方法
SPRING("春天", "春暖花開"){
@Override
public void show() {
System.out.println("春天在哪里");
}
},// 括號(hào)中含屬性
SUMMER("夏天", "夏日炎炎"){
@Override
public void show() {
System.out.println("粉紅色的回憶");
}
},
AUTUMN("秋天", "秋高氣爽"){
@Override
public void show() {
System.out.println("盛夏的果實(shí)");
}
},
WINTER("冬天", "冰天雪地"){
@Override
public void show() {
System.out.println("2002年的第一場雪");
}
};
//2.聲明Season對象的屬性:private final修飾,對象地址不變
private final String seasonName;
// 2.私有化構(gòu)造器,并給對象屬性賦值,在構(gòu)造器里賦值每個(gè)對象屬性值可以不一樣
private final String seasonDesc;
private Season1(String seasonName, String seasonDesc){
this.seasonName = seasonName;
this.seasonDesc = seasonDesc;
}
// 4.訴求1.獲取枚舉類對象的屬性
public String getSeasonName() {
return seasonName;
}
public String getSeasonDesc() {
return seasonDesc;
}
// 5.訴求2.提供重寫的toString()
// 已經(jīng)給重寫過了,默認(rèn)打印對象的名字
/*@Override
public String toString() {
return "Season1{" +
"seasonName='" + seasonName + '\'' +
", seasonDesc='" + seasonDesc + '\'' +
'}';
}*/
@Override
public void show() {
System.out.println("這是個(gè)季節(jié)");
}
}
10.2.注解(Annotation)
- 如何自定義注解
① 注解聲明為: @interface
② 內(nèi)部定義成員,通常使用value表示
③ 可以指定成員的默認(rèn)值,用default定義
④ 如果自定義注解沒有成員,表明是一個(gè)標(biāo)識(shí)作用,例如Override
如果注解有成員,在用注解時(shí),要指明成員的值
自定義注解必須配上注解的信息處理流程(使用反射)才有意義
@MyAnnotation(value = "hi") // 有成員需要指定值,注解加默認(rèn)值,小括號(hào)可省略
public @interface MyAnnotation {
// 自定義注解
String[] value() default "hello"; // 可加默認(rèn)值,
}
4.jdk提供的4種元注解
元注解: 對現(xiàn)有的注解進(jìn)行解釋說明的注解
Retention: 指定所修飾的Annotation 的生命周期: SOURCE\CLASS(默認(rèn)行為)\RUNTIME(只有聲明為RUNYIME生命周期的注解,才能通過反射獲取,必須加載到內(nèi)存中
Target: 指明修飾的注解可以修飾其他哪些結(jié)構(gòu)
********出現(xiàn)頻率較低********
Documented: 表示所修飾的注解在被javadoc解析時(shí),保留下來,默認(rèn)的時(shí)候注解是不保留的
Inherited:被它修飾的Annotation將具有繼承性.父類有了被它修飾的注解,子類也會(huì)有
5.通過反射獲取注解信息 --- 到反射內(nèi)容是系統(tǒng)講解
6.jdk8中注解的新特性: 可重復(fù)注解,類型注解
6.1.可重復(fù)注解: 可以重復(fù)定義多個(gè)的注解
①在MyAnnotation上聲明@Repeatable,成員值為MyAnnotation.class ; 就讓這兩個(gè)注解關(guān)聯(lián)在一起
MyAnnotation的Target和Rentention等其他元注解和MyAnnotation相同
6.2.類型注解:
ElementType.TYPE_PARAMETER: 表示該注解能寫在類型變量的聲明語句中(如:泛型聲明)
ElementType.TYPE_USE: 表示該注解能寫在使用類型的任何語句中
public class AnnotationTest {
public static void main(String[] args) {
Person p = new Student();
p.walk();
@Deprecated // 表示修飾的元素(類,方法等)已過時(shí)
Date date = new Date(2020, 10, 11);
System.out.println(date);
@SuppressWarnings("unused")// 抑制編譯器編譯時(shí)警告
int num = 10;
@SuppressWarnings({"unused","rawtypes"})
ArrayList list = new ArrayList();
}
@Test
public void testGetAnnotation() {
Class clazz = Student.class;
Annotation[] annotations = clazz.getAnnotations();
for (int i = 0; i < annotations.length; i++) {
System.out.println(annotations[i]);
}
}
}
// 重復(fù)注解寫法,但這樣寫會(huì)報(bào)錯(cuò)
@MyAnnotation(value = "hi") // 有成員需要指定值,注解加默認(rèn)值,小括號(hào)可省略
@MyAnnotation(value = "abc")
// 以前的寫法要重新創(chuàng)建一個(gè)注解數(shù)組,呈現(xiàn)出來還是一個(gè)結(jié)構(gòu)
// @MyAnnotations({@MyAnnotation(value = "hi"),@MyAnnotation(value = "abc")})
class Person{
private String name;
private int age;
public Person() {
}
@MyAnnotation
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void eat(){
System.out.println("人吃飯");
}
public void walk(){
System.out.println("人走路");
}
}
interface Info{
void show();
}
class Student extends Person implements Info{
@Override
public void walk() {
System.out.println("學(xué)生走路");
}
@Override
public void show() {
}
}
// 在注解中的Target注解加入TYPE_PARAMETER,TYPE_USE就不會(huì)報(bào)錯(cuò)
class Generic<@MyAnnotation T>{
public void show()throws @MyAnnotation RuntimeException{
ArrayList<@MyAnnotation String> list = new ArrayList<>();
int num = (@MyAnnotation int) 10L;
}
}
@Inherited
@Retention(RetentionPolicy.RUNTIME)// 可以通過反射獲取此注解
@Repeatable(MyAnnotations.class)
@Target({ElementType.TYPE, ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER,ElementType.CONSTRUCTOR,ElementType.LOCAL_VARIABLE,ElementType.TYPE_PARAMETER,ElementType.TYPE_USE})
public @interface MyAnnotation {
// 自定義注解
String[] value() default "hello"; // 可加默認(rèn)值,
}
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.FIELD,ElementType.METHOD,ElementType.PARAMETER,ElementType.CONSTRUCTOR,ElementType.LOCAL_VARIABLE})
public @interface MyAnnotations {
// 聲明一個(gè)MyAnnotation類型的數(shù)組
MyAnnotation[] value(); // 這是個(gè)屬性
}