Java 第十一章总结 枚举与泛型

您所在的位置:网站首页 java枚举使用泛型参数 Java 第十一章总结 枚举与泛型

Java 第十一章总结 枚举与泛型

2023-07-19 02:17| 来源: 网络整理| 查看: 265

11.1 枚举

(1) 使用枚举类型设置常量

在项目中创建Constants接口,在接口中定义常量的常规方式。

public interface Constants{

        public static final int Constants_A=1;

public static final int Constants_B=12;

使用枚举类型定义变量的语法如下:

public enum Constants{

Constants_A,

Constants_B,

Constants_C

}

(2)深入了解枚举类型

1.操作枚举类型成员的方法

1)values()

        枚举类型实例包含一个values()方法,该方法可以将枚举类型成员以数组的形式返回。

例:

package eleven02;   import static java.lang.System.out;   public class ShowEnum {     enum Constants2 { // 将常量放置在枚举类型中         Constants_A, Constants_B     }       // 循环由values()方法返回的数组     public static void main(String[] args) {         for (int i = 0; i < Constants2.values().length; i++) {             // 将枚举成员变量打印             out.println("枚举类型成员变量:" + Constants2.values()[i]);         }     } } 运行结果如下:

 

2)valueOf() 与 compareTo()

        枚举类型中静态方法valueOf()可以将普通字符串转换为枚举类型,而compareTo()方法用于比较两个枚举类型成员定义时的顺序。调用 comparo eTo()方法时,如果方法中参数在调用该方法的枚举对象位置之前,则返回正整数;如果两个互相比较的枚举成员的位置相同,则返回 0;如果方法中参数在调用该方法的枚举对象位置之后,则返回负整数。

例:

package eleven03;   import static java.lang.System.out;   public class EnumMethodTest {     enum Constants2 { // 将常量放置在枚举类型中         Constants_A, Constants_B, Constants_C, Constants_D     }       // 定义比较枚举类型方法,参数类型为枚举类型     public static void compare(Constants2 c) {         // 根据values()方法返回的数组做循环操作         for (int i = 0; i < Constants2.values().length; i++) {             // 将比较结果返回             out.println(c + "与" + Constants2.values()[i] + "的比较结果为:" + c.compareTo(Constants2.values()[i]));         }     }       // 在主方法中调用compare()方法     public static void main(String[] args) {         compare(Constants2.valueOf("Constants_B"));     } } 运行结果如下:

 

3)ordinal()

        枚举类型中的ordinal()方法用于获取某个枚举对象的位置索引值。

例:

package eleven04;   public class EnumIndexTest {     enum Constants2 { // 将常量放置在枚举类型中         Constants_A, Constants_B, Constants_C     }       public static void main(String[] args) {         for (int i = 0; i < Constants2.values().length; i++) {             // 在循环中获取枚举类型成员的索引位置             System.out.println(Constants2.values()[i] + "在枚举类型中位置索引值" + Constants2.values()[i].ordinal());         }     } } 运行结果如下:

 2.枚举类型中的构造方法

在枚举类型中,可以添加构造方法,但是规定这个构造方法必须为 private 修饰符或者默认修饰符所修饰。枚举类型定义的构造方法语法如下:

public enum Constants2{     Constants_A("我是枚举成员A"),     Constants_B("我是枚举成员B"),     Constants_C("我是枚举成员C"),     Constants_D(3);     String description;     int i;       private Constants2(){ //定义默认构造方法      }         //定义带参数的构造方法,参数类型为字符串型         private Constants2(String description){         this.description=description;         private Constants2(int i){//定义带参数的构造方法,参数类型为整型         this.i=this.i+i;     } }          从枚举类型构造方法的语法中可以看出,无论是无参构造方法还是有参构造方法,修饰权限都为private。

        定义一个有参构造方法后,需要对枚举类型成员相应地使用该构造方法,如Constants_A(我是枚举成员A")和 Constants_D(3)语句,相应地使用了参数为 String 型和参数为 int 型的构造方法。然后可以在枚举类型中定义两个成员变量,在构造方法中为这两个成员变量赋值,这样就可以在枚举类型中定义该成员变量的getXXX()方法了。

例:

package eleven05;   import static java.lang.System.out;   public class EnumConTest {     enum Constants2 { // 将常量放置在枚举类型中         Constants_A("我是枚举成员A"), // 定义带参数的枚举类型成员         Constants_B("我是枚举成员B"),          Constants_C("我是枚举成员C"),          Constants_D(3);         private String description;         private int i = 4;           private Constants2() {         }           // 定义参数为String型的构造方法         private Constants2(String description) {             this.description = description;         }                  // 定义参数为int型的构造方法         private Constants2(int i) {              this.i = this.i + i;         }           // 获取description的值         public String getDescription() {              return description;         }           // 获取i的值         public int getI() {              return i;         }     }       public static void main(String[] args) {         for (int i = 0; i < Constants2.values().length; i++) {             out.println(Constants2.values()[i] + "调用getDescription()方法为:" + Constants2.values()[i].getDescription());         }         out.println(Constants2.valueOf("Constants_D") + "调用getI()方法为:" + Constants2.valueOf("Constants_D").getI());     } } 运行结果如下:

 还可以将这个 getDescription()方法放置在接口中,使枚举类型实现该接口,然后使每个枚举类型实现接口中的方法。

package eleven06;   public interface EnumInterface {     public String getDescription();       public int getI(); } package eleven06;   import static java.lang.System.out;     public enum AnyEnum implements EnumInterface {     Constants_A { // 可以在枚举类型成员内部设置方法         public String getDescription() {             return ("我是枚举成员A");         }           public int getI() {             return i;         }     },     Constants_B {         public String getDescription() {             return ("我是枚举成员B");         }           public int getI() {             return i;         }     },     Constants_C {         public String getDescription() {             return ("我是枚举成员C");         }           public int getI() {             return i;         }     },     Constants_D {         public String getDescription() {             return ("我是枚举成员D");         }           public int getI() {             return i;         }     };     private static int i = 5;       public static void main(String[] args) {         for (int i = 0; i < AnyEnum.values().length; i++) {             out.println(AnyEnum.values()[i] + "调用getDescription()方法为:" + AnyEnum.values()[i].getDescription());             out.println(AnyEnum.values()[i] + "调用getI()方法为:" + AnyEnum.values()[i].getI());         }     } } 运行结果如下:

 

 注:

        1)从上面代码中可以看出,枚举类型可以实现一个或者多个接口,但是它不能继承类。因为编译器会默认将枚举类型继承自java.lang.Enum 类,这一过程由编译器完成。         2)枚举类型中的常量成员必须在其他成员之前定义,否则这个枚举类型不会产生对象。

3.使用枚举类型的优势

        枚举类型声明提供了一种用户友好的变量定义方法,枚举了某种数据类型所有可能出现的值。总结枚举类型,它具有以下特点:

(1)类型安全。 (2)紧凑有效的数据定义。 (3)可以和程序其他部分完美交互。

(4)运行效率高11.2 泛型

1.回顾“向上转型”与“向下转型” 例:

package eleven07;   public class Test {     private Object b; // 定义Object类型成员变量       public Object getB() { // 设置相应的getXXX()方法         return b;     }       public void setB(Object b) { // 设置相应的setXXX()方法         this.b = b;     }       public static void main(String[] args) {         Test t = new Test();         t.setB(new Boolean(true)); // 向上转型操作         System.out.println(t.getB());         t.setB(new Float(12.3));         Float f = (Float) (t.getB()); // 向下转型操作         System.out.println(f);     } }

2.定义泛型类         Object类为最上层的父类,很多程序员为了使程序更为通用,设计程序时通常使传入的值与返回的值都以Object类型为主。当需要使用这些实例时,必须正确地将该实例转换为原来的类型,否则在运行时将会发生ClassCastException异常。         在JDK1.5 版本以后,提出了泛型机制。其语法如下:

类名

        其中,T代表一个类型的名称。

将上一个代码改为定义类时使用泛型的形式。

package eleven07;   public class OverClass { // 定义泛型类     private T over; // 定义泛型成员变量       public T getOver() { // 设置相应的getXXX()方法         return over;     }       public void setOver(T over) { // 设置相应的setXXX()方法         this.over = over;     }       public static void main(String[] args) {         //实例化一个Boolean型的对象         OverClass over1 = new OverClass();         //实例化一个Float型的对象         OverClass over2 = new OverClass();         over1.setOver(true);         over2.setOver(12.3f);         Boolean b = over1.getOver();         Float f = over2.getOver();          System.out.println(b);         System.out.println(f);     } }

  使用泛型这种形式将不会发生ClassCastExce ption 异常,因为在编译器中就可以检查类型匹配是否正确。

        例如,在项目中定义泛型类。

OverClass over2=new OverClass();  over2.setover(12.3f); //Integer i=over2.getOver();//不能将F1 oat型的值赋予Integer变量

注:

        在定义泛型类时,一般类型名称使用T来表达,而容器的元素使用E来表达,具体的设置读者可以参看JDK 5.0以上版本的API。

3.泛型的常规用法 定义泛型类时声明多个类型         在定义泛型类时,可以声明多个类型。语法如下:

MutiOverClass MutiOverClass:泛型类名称

        其中,T1 和 T2 为可能被定义的类型。这样在实例化指定类型的对象时就可以指定多个类型。

MutiOverClass=new Mutid OverClass();

定义泛型类时声明数组类型         定义泛型类时也可以声明数组类型,下面的实例中定义泛型时便声明了数组类型。

例:

package eleven08;   public class ArrayClass {     private T[] array; // 定义泛型数组       public void SetT(T[] array) { // 设置SetXXX()方法为成员数组赋值         this.array = array;     }       public T[] getT() { // 获取成员数组         return array;     }       public static void main(String[] args) {         ArrayClass a = new ArrayClass();         String[] array = { "成员1", "成员2", "成员3", "成员4", "成员5" };         a.SetT(array); // 调用SetT()方法         for (int i = 0; i < a.getT().length; i++) {             System.out.println(a.getT()[i]); // 调用getT()方法返回数组中的值         }     } }  

 

此可见,可以在使用泛型机制时声明一个数组,但是不可以使用泛型来建立数组的实例。例如,下面的代码就是错误的:

public class ArrayClass {     //private T[] array=newT[10]; //不能使用泛型来建立数组的实例     ... } 注:

JDK1.7版本中添加了一个新特性:自动推断实例化类型的泛型。所以这样的语法:         ArrayClass a = new ArrayClass();

        // 实现类的泛型为空会自动转换为:         ArrayClass a = new ArrayClass();

集合类声明容器的元素         实际应用中,通过在集合类中应用泛型可以使集合类中的元素类型保证唯一性,这样在运行时就不会产生ClassCastException异常,提高了代码的安全性和可维护性。可以使用K和V两个字符代表容器中的键值和与键值相对应的具体值。

例:

package eleven09;   import java.util.*;   public class MutiOverClass {     public Map m = new HashMap(); // 定义一个集合HashMap实例     // 设置put()方法,将对应的键值与键名存入集合对象中       public void put(K k, V v) {         m.put(k, v);     }       public V get(K k) { // 根据键名获取键值         return m.get(k);     }       public static void main(String[] args) {         // 实例化泛型类对象         MutiOverClass mu = new MutiOverClass();         for (int i = 0; i < 5; i++) {             // 根据集合的长度循环将键名与具体值放入集合中             mu.put(i, "我是集合成员" + i);         }         for (int i = 0; i < mu.m.size(); i++) {             // 调用get()方法获取集合中的值             System.out.println(mu.get(i));         }     } }   运行结果如下:

 

上面例子中泛型类 MutiOverClass 纯属多余,因为在 Java 中集合架已经被泛型化了,可以在主方法中直接使用public Map m=new HashMap0;语句创建实例,然后相应调用Map接口中的 put()与get()方法完成填充容器或根据键名获取集合中具体值的功能。

        集合中除了HashMap 这种集合类型之外,还包括 ArrayList、Vector等。表11.2列举了几个常用的被泛型化的集合类。                                                 常用的被泛型化的集合类

集合类泛型定义HashMapArrayListHashMapHashMapHashSetHashSetVectorVector

4.泛型的高级用法

        泛型的高级用法主要包括通过类型参数T的继承和通过类型通配符的继承来限制泛型类型,另 外,开发人员还可以继承泛型类或者实现泛型接 口,本节将对泛型的一些高级用法进行讲解。

通过类型参数T的继承限制泛型类型         默认可以使用任何类型来实例化一个泛型类对象,但Java中也对泛型类实例的类型作了限制,这主要通过对类型参数T实现继承来体现,语法如下:

class 类名称

例:

package eleven;   import java.util.*;   public class LimitClass { // 限制泛型的类型       public static void main(String[] args) {                  // 可以实例化已经实现List接口的类         LimitClass l1 = new LimitClass();         LimitClass l2 = new LimitClass();                  // 这句是错误的,因为HashMap没有实现List()接口         LimitClass l3 = new LimitClass();     }   } 通过类型通配符的继承限制泛型类型            在泛型机制中,提供了类型通配符,其主要作用是在创建一个泛型类对象时,限制这个泛型类的类型,或者限制这个泛型类型必须继承某个接口或某个类(或其子类)。要声明这样一个对象可以使用“?”通配符,同时使用 extends 关键字来对泛型加以限制。

注: 

        通过对类型参数T 过对类型通配符实现继承限制泛型类型时,则在实例化时才进行限制。

使用泛型类型通配符的语法如下:

泛型类名称 l2 = l1; // 使用通配符         List l3 = new LinkedList();         System.out.println("l1:" + l1.get(0)); // 获取l1集合中第一个值         System.out.println("l2:" + l2.get(0)); // 获取l2集合中第一个值         l1.set(0, "成员改变"); // 没有使用通配符的对象调用set()方法         // l2.add("添加");// 使用通配符的对象不能调用add方法         // l2.set(0, "成员改变"); // 使用通配符的对象不能调用set()方法         // l3.add(1);         // l3.set(0, 1);         System.out.println("l1:" + l1.get(0)); // 可以使用l1的实例获取集合中的值     } } 运行结果如下:

技巧:

        泛型类型限制除了可以向下限制之外,还可以向上限制,只要在定义时使用super 关键字即可。例如,A



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3