枚举类型与泛型

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关键字限制泛型的类型;

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值