您的位置:首页 > 职场人生

黑马程序员_枚举和泛型总结

2014-12-22 23:19 274 查看
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流!
-------



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

一、枚举类型

1.1使用枚举类型设置常量

以往设置常量时,通常将常量放置在接口中,这样在程序中就可以直接使用,并且该常量不能被修改,因为在接口中定义常量时,该常量的修饰符为final和static。例如:

public interface Constants{

public static final int A = 1;

public static final int B = 2;

}

在JDK1.5版本新增枚举类型之后就逐渐取代了这种常规的定义方式。使用枚举类型定义常规的语法

public enum Constants{

A;


B;

}

其中,enum是定义枚举类型的关键字。当需要在程序中使用该常量时,可以使用Constants.A来表示。

枚举类型也可以在类的内部进行定义。

public class ConstantsTest{

enum Constants2{

Constants_A;

Constants_B;

}

}

这种形式类似于内部类形式,当编译时,除了ConstantsTest.class外,还存在ConstantsTest$Constants2.class文件。

1.2深入了解枚举类型

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

枚举类型较传统定义常量的方式,除了具有参数类型检测的优势之外,还巨头其他方面的优势。

用户可以将一个枚举类型看做是一个类,它继承了java.lang.Enum类,当定义一个枚举类型的时候,每一个枚举类型成员都可以看做是枚举类型的实例,这些枚举类型成员都被默认的public final static 修饰,所以当使用枚举类型成员的时候,直接使用枚举类型名称调用枚举类型成员即可。

枚举类型中常用的方法

方法名称
具体含义 使用方法


values()
该方法可以将枚举类型成员以数组的形式返回 枚举类型名称.values()


valueOf()
该方法可以实现将普通字符串转化为枚举实例 枚举类型名称.valueOf()


compareTo()
该方法用于比较两个枚举对象在定义时的顺序 枚举对象.compareTo()


ordinal()
该方法用于得到枚举成员的索引位置 枚举对象.ordinal()


注意:调用compareTo()方法返回的结果,正值代表方法中参数在调用该方法的枚举对象位置之前,0代表相同的位置,负值则代表在其后。

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


enum
Constants2{


Constants_A("我是枚举成员A");

Constants_B("我是枚举成员B");

Constants_C("我是枚举成员C");

Constants_D(3);

private String str;

private int i;

private Constants2(){

}

private Constants2(String str){

this.str = str;

}

private Constants2(int i){

this.i = i;

}

}

在枚举类型中可以添加构造方法,但是贵点这个构造方法必须为private修饰符所修饰的。枚举类型构造方法中,可以有默认的空参数的构造方法,也可以有带参数的构造方法。无论是空参数的还是有参数的构造方法,修饰权限都为private。定义一个有参数的构造方法后,需要对枚举类型成员相应的使用该构造方法,如Constants_A("我是枚举成员A")和Constants_D(3)语句,相应的使用了参数为String 和int型的构造方法。然后可以再枚举类型中定义两个成员变量,在构造方法中赋值,这样就可以在枚举类型中定义成员变量getXXX()方法了。张孝祥老师视频中有带有抽象方法的枚举。将获得枚举对象的方法抽象化,想获取枚举对象,必须是子类复写抽象方法。

调用getXXX()方法返回在枚举类型定义的构造方法中设置的操作。这里需要对方法进行private修饰,以防止客户代码实例化一个枚举对象。此外还可以将这些方法封装在接口中,使枚举类实现这个接口,然后每个枚举类型去实现这个接口中的方法。

1,3使用枚举类型的优势

枚举类型声明提供了一种用户友好的变量定义法,枚举了某种数据类型所有可能出现的值。

(1)类型安全

(2)紧凑有效的数据定义

(3)可以和程序的其他部分完美互交

(4)运行效率高

二、泛型

泛型实质上就是使程序员定义安全的类型。

2,1 回顾“向上转型”和“向下转型”

在向上和向下转型时通常会出现问题,向上转型相对安全,,而如果向下转型操作时用错了类型,或者没有执行该操作,就会出现异常,例如:将父类转换为子类的时候,并不存在语法的错误,所以编译器是可以接受的,但是在运行的时候会抛出类型转换异常。而定义泛型可以解决这一问题。

2,2 定义泛型类

Object类为最上层的类,很多程序员为了使程序更为通用,设计程序时通常使传入的值与返回值都以Object类型为主。当需要使用这些实例的时候,必须正确的将该实例转换为原来的类型,否则在运行时就会发生类型转换异常。

泛型语法:

类名<T>

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

在使用泛型定义的类在声明该类对象时可以根据不同的需求指定<T>真正的类型,而在使用类中的方法传递或者返回数据类型时将不再需要进行类型转换操作,而是使用在声明泛型类对象时<>符号总设置的数据类型。

定义泛型类时,一般类型名称使用T来表示,而容器中的元素使用E来表示。

2.3泛型的常规用法

(1)定义泛型时声明多个类型

在定义泛型的时候,可以声明多个类型。

Demo<T,T>;

实例化对象的时候:

Demo<String,int> d = new Demo<String,int>();

(2) 定义泛型类时声明数组型数据

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 [ ] arry = {"成员1","成员2","成员3"};

a.setT(array);

for(int i = 0;i<a.getT().length;i++){

System.out.pringtln(a.getT()[i]);

}

}

}

可见,可以在使用泛型机制时声明一个数组,但是不可以使用泛型来建立数组实例。

例如,下面代码是错误的

public class ArrayClass<T>{

private T [ ] array = new T [ 9 ];
//不可以使用泛型来建立数组实例


}

(3)集合类声明容器中的元素类型

常用的被泛型化的集合类

集合类
泛型定义


ArrayList
ArrayList <E>


HashMap
HashMap<K,V>


HashSet
HashSet<E>


Vector
Vector<E>


2.4 泛型的高级用法

(1)限制泛型可用类型

默认可以使用任何类型来实例化一个泛型对象,但java中也对泛型类实例的类型做了限定。例如

class 类名称<T extends anyClass>

其中 anyClass是指某个类或者接口。

使用泛型限定后,泛型类的类型必须实现或继承了anyClass这个接口或者类。注意,无论anyClass是
接口还是类,在泛型中必须使用extends关键字。当没有使用extends关键字限制泛型类型时,默认Object类
下的所有子类都可以实例化泛型类对象。


(2)使用类型通配符

在泛型机制中,提供了类型通配符,其主要作用是在创建一个泛型对象时限定这个泛型类的类型实现
或继承某个接口或类的子类。要声明这样一个对象可以使用?通配符来表示,同时使用extends关键字来对
泛型进行加以限定。


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


其中<?extends List>表示未知类型,当需要使用该泛型对象时,需要单独实例化。

A<?extends List> a = null;

a = new A<ArrayList>();

a = new A<LinkedList>();


如果实例化没有实现List接口的泛型对象,编译器就会报错。

除了可以实例化一个限制泛型类型的实例之外,还可以将该实例放置在方法的参数中。

public void show(A<?extends List> a){

}

泛型类型限制除了可以向下限制之外,也可以向上限制。此时需要使用到关键字super。如:

A<?super List> a= null;

这样定以后,对象a只接受List接口后者上层父类类型。

(3)继承泛型类与实现泛型接口

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

public class A<T1>{ }

class B<T1,T2,T3>extends A<T1> { }

如果在B类继承了A类时保留父类的泛型类型,需要再继承的时候指明,如果没有指明而直接使用B
extends 语句进行继承,则B类中的T1,T2,T3都会自动变为Object,所以在一般的情况下都将父类的泛型类
型保留下来。


2.5 泛型总结

(1)泛型的类型参数只能是类类型,不可以是简单类型,如A<int>这种就是错误的。

(2)泛型的类型个数可以是多个

(3)可以使用extends 关键字限制泛型类型

(4)可以使用通配符限制泛型的类型
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐