枚举类型与泛型

来源:互联网 发布:个人网站导航页源码 编辑:程序博客网 时间:2024/06/03 21:55

JDK1.5中新增了枚举类型和泛型,枚举类型可以取代以往常量的定义方式,将常量封装在类或接口中,还提供了安全检查功能。枚举类型本质上还是以类的形式存在。泛型的出现不仅可以让程序员少写很多代码,主要的作用是解决类型安全问题,提供编译时的安全检查,不会因为将对象置于某个容器中而失去类型。

  • 枚举类型
以往定义常量的方式使用接口,这样在程序中可以直接被使用,而且该常量不能被修改,接口中定义常量是修饰符为final和static,如下实例:

package enumeration.simple;public interface ConstantDemos {public static final int Constants_A = 1;public static final int Constants_B = 12;}
JDK1.5以后采用枚举类型代替常量定义方式:

package enumeration.simple;public enum Constants {Constants_A, Constants_B,Constants_C}
其中enum为定义枚举类型的关键字,可以通过Constants.Constants_A的方式进行调用。
编译器即使没有接收到接口中定义的常量参数,也不会报错;但如果是枚举类型,该方法就只能接收枚举类型的常量作为参数,其他任何形式都会报错。枚举类型与传统定义常量的方式相比具有类型检测的功能。

package enumeration;interface Constants1{public static final int CONSTANTS_A = 1;public static final int CONSTANTS_B = 2;}public class ConstantsTest {enum Constants2 {CONSTANTS_A, CONSTANTS_B}public static void doit(int c){switch(c){case Constants1.CONSTANTS_A:System.out.println("diot: CONSTANTS_A");break;case Constants1.CONSTANTS_B:System.out.println("diot: CONSTANTS_B");break;}}public static void doit2(Constants2 c){switch(c){case CONSTANTS_A:System.out.println("diot2: CONSTANTS_A");break;case CONSTANTS_B:System.out.println("diot2: CONSTANTS_B");break;}}public static void main(String[] args) {// 不接收常量参数也不会报错ConstantsTest.doit(Constants1.CONSTANTS_A);// 必须是枚举类型ConstantsTest.doit2(Constants2.CONSTANTS_A);ConstantsTest.doit2(Constants2.CONSTANTS_B);ConstantsTest.doit(3);}}
另外,枚举类型可以看作是一个类,而每个枚举类型成员都可以看作是枚举类型的一个实例,枚举类型成员默认都是被final、public、static修饰。而且枚举类型的类都继承自java.lang.Enum类,该类中有操作枚举类型的方法:

values():将枚举类型的成员以数组的形式返回;

valueOf():将普通字符串转为枚举类型的实例;

compareTo():用于比较两个枚举对象在定义时的顺序;

ordinal():用于得到枚举成员的索引位置;

package enumeration;public class ShowEnum {enum Constants2{Constants_a, Constants_b}public static void compare(Constants2 c){for(int i = 0; i < Constants2.values().length; i++){System.out.println(c + " and " + Constants2.values()[i] + " compare and result is " + c.compareTo(Constants2.values()[i]));}}public static void main(String[] args) {for(int i = 0; i < Constants2.values().length; i++){System.out.println(Constants2.values()[i]);}compare(Constants2.Constants_a);for(int i = 0; i < Constants2.values().length; i++){System.out.println(Constants2.values()[i].ordinal());}}}
package enumeration;public class EnumIndexTest {enum Constants2{Constants_A, Constants_B, Constants_C, Constants_D;}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());}}}
枚举类型种可以添加构造方法,但是规定必须为private修饰符锁修饰。

package enumeration.simple;public class EnumIndexTest {enum Constants{Constants_A("a"),Constants_B("b"),Constants_C(1);private String des;private int i = 4;private Constants(){}private Constants(String des){this.des = des;}private Constants(int i){this.i = this.i + i;}public String getDes(){return des;}public int getI(){return i;}}public static void main(String[] args) {for(int i = 0; i < Constants.values().length; i++){System.out.println(Constants.values()[i] + "---" + Constants.values()[i].getDes());}System.out.println(Constants.valueOf("Constants_C") + "---" + Constants.valueOf("Constants_C").getI());}}
使用枚举类型的优势为:

类型安全;

紧凑有效的数据定义;

运行效率高;

可以和程序其他部分完美交互;

  • 泛型
在没有泛型之前,Java也提供了对Object的引用任意化的 操作,对Object引用进行向下转型及向上转型(通常向下转型会出现问题),但是某些强制类型转换不会被编译器捕捉,而在运行时出现异常,所以出现了泛型机制。

T代表一个类型的名称。

package genericity;public class OverClass<T> {private T over;public T getOver(){return over;}public void setOver(T over){this.over = over;}public static void main(String[] args) {OverClass<Boolean> over1 = new OverClass<Boolean>();OverClass<Float> over2 = new OverClass<Float>();over1.setOver(true);over2.setOver(67.9F);System.out.println(over1.getOver());System.out.println(over2.getOver());}}
使用泛型这种形式将不会发生ClassCastException异常,因为在编译器中就可以检查类型匹配是否正确。
定义泛型类时声明数组类型

package genericity;public class ArrayClass<T> {private T[] array;public void setT(T[] array){this.array = array;}public T[] getT(){return array;}public static void main(String[] args) {ArrayClass<String> a = new ArrayClass<String>();String[] arr = {"num1", "num2", "num3", "num4"};a.setT(arr);for(int i = 0; i < a.getT().length; i++){System.out.print(a.getT()[i] + " ");}}}
可以在使用泛型机制时声明一个数组,但是不可以使用泛型来建立数组的实例。
常用的被泛型化的集合类:

ArrayList<E>、HashMap<K,V>,HashSet<E>,Vector<E>;

限制泛型可用类型

class 类名称<T extends anyClass>,其中anyClass可以是类或接口,但都必须使用extends关键字。

package genericity;import java.util.ArrayList;import java.util.LinkedList;import java.util.List;public class LimitClass<T extends List> {LimitClass<ArrayList> l1 = new LimitClass<ArrayList>();LimitClass<LinkedList> l2 = new LimitClass<LinkedList>();LimitClass<List> l3 = new LimitClass<List>();}
使用类型通配符

泛型类名称<? extends List> a = null;

A<? extends List> a = null;

a = new A<ArrayList>();

a = new A<LinkedList>();

注意:使用通配符创建出来的集合对象,不能改变集合中的值。

定义为泛型的类和接口也可以被继承与实现,

package genericity;public class ExtendClass<T1> {class SubClass<T1, T2, T3> extends ExtendClass<T1>{}}
package genericity;public interface i<T1> {class SubClass<T1, T2, T3> implements i<T1>{}}
泛型总结:

泛型的类型参数只能是类类型,不能是简单基本类型,如A<int>这种方式定义是错误的;

泛型的类型参数可以是多个;

可以使用extends关键字限制泛型的类型;

可以使用通配符限制泛型的类型;



原创粉丝点击