1. 程式人生 > >java基礎知識總結7(列舉+泛型)

java基礎知識總結7(列舉+泛型)

七、列舉

列舉是一個類型別,是JDK1.5的新特性
列舉的關鍵字是enum
Java中所有的列舉類都是java.lang.Enum的子類

注意:列舉類中可以包含成員有【欄位(常量)、方法(構造方法、普通方法)】

列舉中不能有number;不能賦值————類

只有順序可以比較———–

語法:

enum 列舉名{

     列舉體

}

例:

enum Direction{//列舉體

     EAST,SOUTH,WEST,NORTH//後面可以有分號也可以沒有

}

呼叫:列舉名.成員

列舉名 name =列舉名.成員;

Direction dir = Direction.EAST;

Enum的方法使用:

Javap—————檢視位元組碼檔案

程式碼:

enum Direction{

EAST(‘e’),SOUTH(’s’),NORTH(‘n’),WEST(‘w’);

protected char a;

private Direction(char a){

this.a = a;

}

public String toString(){

return a+”“;

}

}

位元組碼:

———- javap ———-

Compiled from “Direction.java”

final class Direction extends java.lang.Enum {//不能被例項化

public static final Direction EAST;

public static final Direction SOUTH;

public static final Direction NORTH;

public static final Direction WEST;

protected char a;//預設是private,但可以使用4P

public static Direction[] values();//預設方法,用來遍歷列印列舉成員

public static Direction valueOf(java.lang.String);

public java.lang.String toString();

static {};//靜態初始化塊

}

由上面可以知道列舉繼承java.lang.Enum類,引數的預設修飾符public static final,在列舉中可以使用4p

public enum A{BLUE,RED,BLACK};//宣告並定義一個列舉,初始化為。。。

在一個類中定義一個enum成員,enum預設是靜態的————-相當於類變數

列舉的用法

一、常量

枚舉出來之前都是通過介面

在JDK1.5 之前,我們定義常量都是: public static fianl,現在可以把相關的常量分組到一個列舉型別裡,例:

public enum Color {

RED, GREEN, BLANK, YELLOW

}

二、Switch

JDK1.5之後的switch語句支援Byte,short,int,char,enum型別,使用列舉,能讓我們的程式碼可讀性更強,JDK1.7之後開始支援String型別,例:

enum Signal {

     GREEN, YELLOW, RED

}

public class TrafficLight {

     Signal color = Signal.RED;

     public void change() {

               switch (color) {

               case RED:

                        color = Signal.GREEN;

                        break;

               case YELLOW:

                        color = Signal.RED;

                        break;

               case GREEN:

                        color = Signal.YELLOW;

                        break;

               }

     }

}

三、向列舉中新增新方法

要自定義方法,必須在enum例項序列的最後新增一個分號。而且 Java 要求必須先定義 enum例項,例:

public enum Color {

     RED("紅色", 1), GREEN("綠色", 2), BLANK("白色", 3), YELLO("黃色", 4);

     // 成員變數

     private String name;

     private int index;

     // 構造方法

     private Color(String name, int index) {

               this.name = name;

               this.index = index;

     }

     // 普通方法

     public static String getName(int index) {

               for (Color c : Color.values()) {

                        if (c.getIndex() == index) {

                                 return c.name;

                        }

               }

               return null;

     }

     // get set 方法

     public String getName() {

               return name;

     }

     public void setName(String name) {

               this.name = name;

     }

     public int getIndex() {

               return index;

     }

     public void setIndex(int index) {

               this.index = index;

     }

}

四、覆蓋列舉的方法

例如覆蓋toString()

public enum Color {

     RED("紅色", 1), GREEN("綠色", 2), BLANK("白色", 3), YELLO("黃色", 4);

     // 成員變數

     private String name;

     private int index;

     // 構造方法

     private Color(String name, int index) {

               this.name = name;

               this.index = index;

     }

     //覆蓋方法

     @Override

     public String toString() {

               return this.index+"_"+this.name;

     }

}

五、實現介面

所有的列舉都繼承自java.lang.Enum類。由於Java 不支援多繼承,所以列舉物件不能再繼承其他類,例:

public interface Behaviour {

     void print();

     String getInfo();

}

public enum Color implements Behaviour{

     RED("紅色", 1), GREEN("綠色", 2), BLANK("白色", 3), YELLO("黃色", 4);

     // 成員變數

     private String name;

     private int index;

     // 構造方法

     private Color(String name, int index) {

               this.name = name;

               this.index = index;

     }

//介面方法

     @Override

     public String getInfo() {

               return this.name;

     }

     //介面方法

     @Override

     public void print() {

               System.out.println(this.index+":"+this.name);

     }

}

六、使用介面組織列舉

public interface Food {

     enum Coffee implements Food{

               BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO

     }

     enum Dessert implements Food{

               FRUIT, CAKE, GELATO

     }

}

七、列舉集合

java.util.EnumSet和java.util.EnumMap是兩個列舉集合。EnumSet保證集合中的元素不重複;EnumMap中的key是enum型別,而value則可以是任意型別。

列舉和普通類的區別與聯絡;

1、列舉與類都可以實現多介面;訪問控制符都可以使用(4p),但列舉中預設的是private,類中預設的是package;

2、列舉直接繼承java.lang.Enum類,普通類是繼承java.lang.Object;其中java.long.Enum類實現了java.long.Serializable和java.long.Comparable兩個介面。

3、使用enum定義、非抽象的列舉預設修飾符為public final,因此列舉不能派生子類。
4、列舉的構造器只能使用private訪問控制符,如果省略了列舉的訪問修飾符其預設為private修飾;因為列舉的欄位不能初始化,物件型別的必須呼叫構造方法,所有有多少個成員構造方法就會執行多少次;
5、列舉的所有例項必須在列舉的第一行顯示列出,否則這個列舉永遠都不能生產例項,列出這些例項時系統會自動新增public static final修飾,無需程式設計師顯式新增

6、所有的列舉類都提供了一個values方法,該方法可以很方便的遍歷所有的列舉值

7、關鍵字:列舉是enum,類是class

8、列舉是類型別,類是引用型別

instanceof關鍵字:
public class FX {
public static void main(String[] args) {
boolean b = (“1” instanceof String);//判斷某個物件是不是某個類的例項 Result = Object instanceof Class/interface
//Result:布林型別。
//Object:必選項。任意物件表示式。
//Class:必選項。任意已定義的物件類。
System.out.println(b);
}
}

註解—JDK1.5的新特性
使用位置:類上、方法上、語句上

八、協變與泛型

協變——-可以用在陣列、重寫,不可以用在列舉中

可變引數:

int… a————-代表一個沒有長度限制的陣列———-JDK1.5之後有的

輸入的必須是陣列

Java1.5增加了新特性:可變引數:適用於引數個數不確定,型別確定的情況,java把可變引數當做陣列處理。注意:可變引數必須位於最後一項。只支援有一個可變引數。因為引數個數不定,所以當其後邊還有相同型別引數時,java無法區分傳入的引數屬於前一個可變引數還是後邊的引數,所以只能讓可變引數位於最後一項。

可變引數的特點:

(1)、只能出現在引數列表的最後;

(2)、… 位於變數型別和變數名之間,前後有無空格都可以;

(3)、呼叫可變引數的方法時,編譯器為該可變引數隱含建立一個數組,在方法體中以陣列的形式訪問可變引數。例:

public class Varable {
public static void main(String [] args){
System.out.println(add(2,3));
System.out.println(add(2,3,5));
}
public static int add(int x,int …args){
int sum=x;
for(int i=0;i

協變的作用範圍

1、陣列:如果 A 是 B 的超類,則 A[] 也是 B[] 的超類,所有需要 A[] 的地方都可以用 B[] 代替,例:

public class Test2 {

public static void main(String[] args){

    Integer[] ints=new Integer[1];

    ints[0]=99;

    show(ints);

}

static void show(Number[] ns){

    System.out.println(Arrays.toString(ns));

}

}

2、重寫

public class Test2 {

public static void main(String[] args){

    P p=new C();

    System.out.println(p.get());

}

}

class P{

public Number get(){

    return new Integer(0);

}

}

class C extends P{

public Integer get(){

    return new Integer(1);

}

}

public class Test2 {

public static void main(String[] args) {

    List<Integer> ints = new ArrayList<Integer>();

    //incompatible type--型別不相容

    show(ints);

}



static void show(List<Number> ns) {

    System.out.println(ns);

}

}

泛型(Generic)的本質是型別引數化

————-是JDK1.5提供的新技術,它的本質是型別引數化,類似C++中的模板,它根據應用主要分為泛型方法,泛型介面,泛型類,協變不適用於泛型

泛型————-泛型類class Demo{},泛型介面interface Inter{},泛型方法public T show(T a) {}

泛型的好處是在編譯的時候檢查型別安全,並且所有的強制轉換都是自動和隱式的,提高程式碼的重用率

例1:
public class GenericDemo{

   public static void main(String[] args) {

          C c1 = new C(new A("aaa"));

          C c2 = new C(new B(3.4));//包裝成double---自動裝箱

          Object obj = c1.getObj();

          A obj = (A)(c1.getObj());//強制轉換

          System.out.println(obj);

   }

}

class A{

   private String x;

   public A(String x){

          this.x=x;

   }

   public String getX(){

          return x;

   }

}

class B{

   private Double d;

   public B(Double d){

          this.d=d ;

   }

   public Double getD(){

          return d;

   }

}

class C{

   private Object obj;

   public C(Object obj){

          this.obj=obj ;

   }

   public Object  getObj(){

          return obj;

   }

}

泛型的使用

一、泛型類:

public class Demo1 {

   public static void main(String[] args) {

          Generic<String> c = new Generic<String>("asad");

          System.out.println(c.getA());



          //Generic<int> c1 = new Generic<int>(12);必須要是包裝類

   }

}

class Generic{//泛型類

   private T a;

   public Generic(T a){

          this.a = a;

   }

   public T getA(){

          return a;

   }

}

二、泛型方法

   public static <T> T getX(T t){//泛型方法----------<  >--表宣告
          return t;

   }

三、泛型介面

public class GenericDemo3{

public static void main(String[] args) {

D < int[][]> d = new D< int[][]>();

d.show(new int[][]{{1,4},{2,3}});

}

}

interface IA{

void show(T t);

}

class D implements IA{

public void show(T t){

System.out.println(t.getClass().getName());

}

}

有界型別:

上界:extends 預設上界為Object

Class G < T extends Number,K extends Object,H super Integer>{}

下界:super———-只有萬用字元有下限

extends關鍵字聲明瞭型別的上界,表示引數化的型別可能是所指定的型別,或者是此型別的子類

super關鍵字聲明瞭型別的下界,表示引數化的型別可能是所指定的型別,或者是此型別的父型別,直至Object

規則和限制

1、泛型的型別引數只能是類型別(包括自定義類),不能是簡單型別。

2、同一種泛型可以對應多個版本(因為引數型別是不確定的),不同版本的泛型類例項是不相容的。

3、泛型的型別引數可以有多個。< T,K>

4、泛型的引數型別可以使用extends關鍵字,例如< T extends superclass>。習慣上稱為“有界型別”。

5、泛型的引數型別還可以是萬用字元型別。例如Class< ? > classType = Class.forName(“java.lang.String”)

6、如果只指定了< ? >,而沒有extends,則預設是允許Object及其下的任何Java類了。也就是任意類。

7、萬用字元泛型不但可以向下限制,如< ? extends Collection >,還可以向上限制,如< ? super Double >,表示型別只能接受Double及其上層父類型別,如Number、Object型別的例項。

8、泛型類定義可以有多個泛型引數,中間用逗號隔開,還可以定義泛型介面,泛型方法。這些都與泛型類中泛型的使用規則類似。

一個普通static方法,無法訪問泛型類的型別引數,所以,若普通static方法需要使用泛型引數,必須使其成為泛型方法。