JDK1.5中新增了枚举类型和泛型,枚举类型可以取代以往常量的定义方式,将常量封装在类或接口中,还提供了安全检查功能。枚举类型本质上还是以类的形式存在。泛型的出现不仅可以让程序员少写很多代码,主要的作用是解决类型安全问题,提供编译时的安全检查,不会因为将对象置于某个容器中而失去类型。
- 枚举类型
package enumeration.simple;JDK1.5以后采用枚举类型代替常量定义方式:
public interface ConstantDemos {
public static final int Constants_A = 1;
public static final int Constants_B = 12;
}
package enumeration.simple;其中enum为定义枚举类型的关键字,可以通过Constants.Constants_A的方式进行调用。
public enum Constants {
Constants_A,
Constants_B,
Constants_C
}
编译器即使没有接收到接口中定义的常量参数,也不会报错;但如果是枚举类型,该方法就只能接收枚举类型的常量作为参数,其他任何形式都会报错。枚举类型与传统定义常量的方式相比具有类型检测的功能。
package enumeration;另外,枚举类型可以看作是一个类,而每个枚举类型成员都可以看作是枚举类型的一个实例,枚举类型成员默认都是被final、public、static修饰。而且枚举类型的类都继承自java.lang.Enum类,该类中有操作枚举类型的方法:
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);
}
}
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());
}
}
类型安全;
紧凑有效的数据定义;
运行效率高;
可以和程序其他部分完美交互;
- 泛型
T代表一个类型的名称。
package genericity;使用泛型这种形式将不会发生ClassCastException异常,因为在编译器中就可以检查类型匹配是否正确。
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());
}
}
定义泛型类时声明数组类型
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关键字限制泛型的类型;
可以使用通配符限制泛型的类型;