枚举类型可以取代以往常量的定义方式,既将常量封装在类或接口中。此外,它还提供了安全检查功能,枚举类型本质上还是以类的形式存在的泛型的出现,不仅可以让程序员少写一些代码更重要的是。它可以解决类型安全问题。泛型提供了编译时的安全检查不会因为将对象置于某个容器中而失去其类型。
所有枚举类的方法都是私有的
13.1:枚举类型:使用枚举类型,可以取代前面学习过的定义常量的方式,代前面学习过的定义常量的方式,同时枚举类型还赋予程序在编译时进行检查的功能。
13.1.1:使用枚举类型设置常量
1:使用枚举类型设置常量设置常量时,我们通常将常量放置在接口中,这样在程序中就可以直接使用该常量不能被修改因为在接口中定义常量时,该常量的修饰符为final与static常规定义常量的代码如下。
package thirteen;
public interface Constants {
public static final int Constants_A=1;//常规定义变量代码
public static final int Constants_B=2;
}
变量代码,public static final int constants_B=2;}枚举类型出现后逐渐取代了。上述常量定义方式使用枚举类型定义常量的语法如下:
public enum Constants{
Constants_A,
Constants_B,
}
其中, enum 是定义枚举类型的关键字,当需要程序中使用该常量时,可以使用Constants和Constants_A来表示。
package thirteen;
interface SeasonInterface { // 四季接口
int SPRING = 1, SUMMER = 2, AUTUMN = 3, WINTER = 4;
}
enum SeasonEnum { // 四季枚举
SPRING, SUMMER, AUTUMN, WINTER
}
public class SeasonDemo{
public static void printSeason1(int season) {
switch (season) {
case SeasonInterface.SPRING:
System.out.println("这是春季");break;//break跳出
case SeasonInterface.SUMMER:
System.out.println("这是夏季");break;
case SeasonInterface.AUTUMN:
System.out.println("这是秋季");break;
case SeasonInterface.WINTER:
System.out.println("这是冬季");break;
default:
System.out.println("这不是四季的常量值");
}
}
public static void printSeason2(SeasonEnum season) {
switch (season) {//switch语句
case SPRING:
System.out.println("这是春季");break;
case SUMMER:
System.out.println("这是夏季");break;
case AUTUMN:
System.out.println("这是秋季");break;
case WINTER:
System.out.println("这是冬季");break;
}
}
public static void main(String[] args) {
printSeason1(SeasonInterface.SPRING); // 使用接口常量做参数
printSeason1(3); // 可以使用数字做出参数
printSeason1(-1); // 也使用接口常量值以外的数字冒充常量
printSeason2(SeasonEnum.WINTER); // 使用枚举做参数,只能用枚举有中的值,无法冒充
}
}
//例题13.1
13.1.2:深入了解枚举类型
枚举类型传统定义常量的方式,除具参数类型检测的优势外,还具有其他方面的优势。用户可以将一个枚举类型看作是一个类,它继承于Java.lang.Enum类,当定义一个枚举类型时,每个枚举类型成员都可以看作是枚举类型的一个实例,这些枚举类型成员都默认被final、 public、 static修饰,所以当使用枚举类型成员时直接使用枚举类型名称调用枚举类型成员即可。由于枚举类型对于继承Java.lang.Enum类,所以该类中一些操作枚举。类型的方法都可以应用到枚举类型中表13.1中列举了枚举类型中的常用方法。
枚举类型中的构造方法:在枚举类型中可以添加构造方法但是规定这个构造方法必须被private修饰符所修饰枚举类型定义的构造方法如下:
enum 枚举类型名称{
Constants_A("我是枚举成员A"),
Constants_B("我是枚举成员B"),
Constants_C("我是枚举成员C"),
Constants_D(3);
privte String description;
private Constants2(){ //定义默认构造方法
}
private Constants2(String description){ //定义带参的构造方法,参数类型为字符串型
this.description = description;
}
private Constants2(int i){ //定义带参数的构造方法,参数类型为整形
this.i = this.i+i;
}
}
从枚举类型构造方法的语法中可以看出,无论是无参构造方法还是有参构造方法,修饰权限都为private。定义一个1有参构造方法,需要对枚举类型成员相应的使用该构造方法。
13.1.3: 使用枚举类型的优势
枚举类型声明提供了一种对用户友好的变量定义方法,枚举了某种类型所有可能出现的值。总结枚举类型,它具有以下特点:
1.类型安全
2.紧凑有效的数据定义
3..可以和程序其他部分完美交互
4.运行效率高
13.2: 泛型
泛型实质上就是使程序员定义安全的类型。在没有出现泛型之前,Java也提供了对object类型的引用“任意化” 操作,这种“任意化”操作就是对object类型引用进行向下转型及向下转型操作,但某些强制类型转换的错误也许不会被编译器捕捉,而在运行后出现异常,可见强制类型转换存在安全隐患,所以在此提供了泛型机制。
13.2.1:回顾向上转型与向下转型
在介绍泛型之前,先来看一个例子,在项目中创建Test类,在该类中使基本类型向上转型为object类型
package thirteen;
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(Boolean.valueOf(true)); //向上转型操作
System.out.println(t.getB());
t.setB(Float.valueOf("12.3")); //向下转型操作
Float f = (Float)t.getB();
System.out.println(f);
}
}
在本实例中,Test类中定义了私有的成员变量b,它的类型为Object类型,同时为其定义了相应的setXXX()与getXXX()方法。在类的主方法中,将Boolean.valueOf(true)作为setB()方法的参数,向下转型会出现错误,语法错误没有出现编译器会接受此段代码,,但执行时会出现ClassCastException异常,而泛型机制就有效解决了这一问题。
示例代码如图所示
public class Javap223 {
testB(Float.valuesOf("12.3"));
Integer f = (Integer)t.getB();
System.out.println(f);
}
13.2.2:定义泛型类
Object类为最上层的父类,为了提前预防发生异常,Java提供了泛型机制其语法如下
类名<T>
package thirteen;
public class Book<T> {
private T bookInfo;
public Book(T bookInfo) {
this.bookInfo = bookInfo;
}
public T getBookInfo() {
return bookInfo;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建参数为String类型的书名对象
Book<String> bookName = new Book<String>("《Java从入门们到精通》");
// 创建参数为String类型的作者对象
Book<String> bookAuthor = new Book<String>("明日科技");
// 创建参数为Double类型的价格对象
Book<Double> bookPrice = new Book<Double>(69.8);
// 创建参数为Boolean类型的附赠源码
Book<Boolean> hasSource = new Book<Boolean>(true);
// 控制台输出书名、作者、价格和是否附赠光盘
System.out.println("书名:" + bookName.getBookInfo());
System.out.println("作者:" + bookAuthor.getBookInfo());
System.out.println("价格:" + bookPrice.getBookInfo());
System.out.println("是否附赠源码?" + hasSource.getBookInfo());
}
}
//例题13.6