枚举类型与泛型
- 枚举类型可以取代以往常量的定义方式,即将常量封装在类或接口中,此外,它还提供了安全检查功能。
- 泛型的出现不仅可以让程序猿少些某些代码,主要的作用是解决类型安全问题,它提供编译时的安全检查,不会因为将对象置于某个容器中而失去其类型。
枚举类型
使用枚举类型设置常量
使用枚举类型定义常量的语法如下:
public enum Constants{
Constants_A,
Constants_B,
Constants_C
}
其中,enum是定义枚举类型关键字。当需要在程序中使用该常量时,可以使用Constants.Constants_A来表示。
深入了解枚举类型
枚举类型较传统定义常量的方式,除了具有**参数类型检测**的优势之外,还具有其他方面的优势
用户可以讲一个枚举类型看作是一个类,它继承与java.lang.Enum类,当定义一个枚举类型时。每一个枚举类型成员都可以看作是枚举类型的一个实例,这些枚举类型成员都默认被final、public、static修饰,所以当使用枚举类型成员时,直接使用枚举类型名称调用枚举类型成员即可。
操作枚举类型成员的方法
枚举类型常用方法:
| 方法名称 | 具体含义 | 使用方法 |
|---|---|---|
| values() | 将枚举类型成员以数组的形式返回 | 枚举类型名称.values() |
| valueOf() | 将普通字符串转换为枚举实例 | 枚举类型名称.valueOf(“abc”) |
| compareTo() | 比较两个枚举对象在定义时的顺序 | 枚举对象.compareTo() |
| ordinal() | 得到枚举成员的位置索引 | 枚举对象.ordinal() |
枚举类型中的构造方法
- 规定枚举类型的构造方法必须为private修饰符所修饰,以防止客户代码实例化一个枚举对象。
定义一个有参构造方法后,需要对枚举类型成员相应地使用该构造方法 例:
import static java.lang.System.*;
public class EnumIndexTest {
enum Constants2 { // 将常量放置在枚举类型中
Constants_A("我是枚举成员A"), // 定义带参数的枚举类型成员
Constants_B("我是枚举成员B"), Constants_C("我是枚举成员C"), Constants_D(3);
private String description;
private int i = 4;
private Constants2() {
}
// 定义参数为String型的构造方法
private Constants2(String description) {
this.description = description;
}
private Constants2(int i) { // 定义参数为整型的构造方法
this.i = this.i + i;
}
public String getDescription() { // 获取description的值
return description;
}
public int getI() { // 获取i的值
return i;
}
}
public static void main(String[] args) {
for (int i = 0; i < Constants2.values().length; i++) {
out.println(Constants2.values()[i] + "调用getDescription()方法为:"
+ Constants2.values()[i].getDescription());
}
out.println(Constants2.valueOf("Constants_D") + "调用getI()方法为:"
+ Constants2.valueOf("Constants_D").getI());
}
}

此外,还可以将这个getDescription()方法设置在接口中,使枚举类型实现该接口。例:
package com.lzw;
import static java.lang.System.*;
interface d {
public String getDescription();
public int getI();
}
public enum AnyEnum implements d {
Constants_A { // 可以在枚举类型成员内部设置方法
public String getDescription() {
return ("我是枚举成员A");
}
public int getI() {
return i;
}
},
Constants_B {
public String getDescription() {
return ("我是枚举成员B");
}
public int getI() {
return i;
}
},
Constants_C {
public String getDescription() {
return ("我是枚举成员C");
}
public int getI() {
return i;
}
},
Constants_D {
public String getDescription() {
return ("我是枚举成员D");
}
public int getI() {
return i;
}
};
private static int i = 5;
public static void main(String[] args) {
for (int i = 0; i < AnyEnum.values().length; i++) {
out.println(AnyEnum.values()[i] + "调用getDescription()方法为:"
+ AnyEnum.values()[i].getDescription());
out.println(AnyEnum.values()[i] + "调用getI()方法为:"
+ AnyEnum.values()[i].getI());
}
}
}
使用枚举类型的优势
枚举类型的特点:
- 类型安全
- 紧凑有效的数据定义
- 可以和程序其他部分完美交互
- 运行效率高
泛型
泛型实质上就是是程序员定义安全的类型
强制类型转换存在安全隐患,所以提供了泛型机制
定义泛型类
语法:
类名<T>
其中,T代表一个类型的名称。
在定义泛型类时,一般类型名称使用 T 来表达,而容器的元素使用 E 来表达。
泛型的常规用法
定义泛型类时声明多个类型
在定义泛型类时,可以声明多个类型。例:
MutiOverClass<T1,T2>
则:
MutiOverClass<Boolean,Float> = new MutiOverClass<Boolean,Float>();
定义泛型类时声明数组类型
例:
public class ArrayClass<T> {
private T[] array; // 定义泛型数组
public void SetT(T[] array) { // 设置SetXXX()方法为成员数组赋值
this.array = array;
}
public T[] getT() { // 获取成员数组
return array;
}
public static void main(String[] args) {
ArrayClass<String> a = new ArrayClass<String>();
String[] array = { "成员1", "成员2", "成员3", "成员4", "成员5" };
a.SetT(array); // 调用SetT()方法
for (int i = 0; i < a.getT().length; i++) {
System.out.println(a.getT()[i]); // 调用getT()方法返回数组中的值
}
}
}
-可以在使用泛型机制时声明一个数组,但是不可以使用泛型来简历数组的实例。
public class ArrayClass<T>{
//private T[] array = new T[10]; //不能使用泛型来简历数组的实例
}
集合类声明容器的元素
可以使用K和V两个字符代表容器中的键值和与键值想对应的具体指。例:
public Map<K,V> m = new HashMap<K,V>();
import java.util.*;
public class AnyClass {
public static void main(String[] args) {
// 定义ArrayList容器,设置容器内的值类型为Integer
ArrayList<Integer> a = new ArrayList<Integer>();
a.add(1); // 为容器添加新值
for (int i = 0; i < a.size(); i++) {
// 根据容器的长度循环显示容器内的值
System.out.println("获取ArrayList容器的值:" + a.get(i));
}
// 定义HashMap容器,设置容器的键名与键值类型分别为Integer与String型
Map<Integer, String> m = new HashMap<Integer, String>();
for (int i = 0; i < 5; i++) {
m.put(i, "成员" + i); // 为容器填充键名与键值
}
for (int i = 0; i < m.size(); i++) {
// 根据键名获取键值
System.out.println("获取Map容器的值" + m.get(i));
}
// 定义Vector容器,使容器中的内容为String型
Vector<String> v = new Vector<String>();
for (int i = 0; i < 5; i++) {
v.addElement("成员" + i); // 为Vector容器添加内容
}
for (int i = 0; i < v.size(); i++) {
// 显示容器中的内容
System.out.println("获取Vector容器的值" + v.get(i));
}
}
}
详情看集合类
泛型的高级用法
泛型的高级用法包括 限制泛型可用类型 和 使用类型通配符
限制泛型可用类型
class 类名称<T extends anyClass>
其中,anyClass指某个接口或类。
在使用泛型限制后,泛型类的类型必须实现或继承了anyClass这个接口或类。无论AnyClass是接口还是类,在进行泛型限制时都必须使用extends 关键字。例:
import java.util.*;
public class LimitClass<T extends List>{//限制泛型的类型
public static void main(String[] args){
//可以实例化已经实现List接口的类
LimitClass<ArrayList> l1 = new LimitClass<ArrayList>();
LimitClass<LinkedList> l2 = new LimitClass<LinkedList>();
//这句是错误的,因为HashMap没有实现List()接口
//LimitClass<HashMap> l3 = new LImitClass<HashMap>();
}
}
使用类型通配符
泛型类型名称<? extends List> a = null;
除了可以实例化一个限制泛型类型的实例之外,还可以将实例放置在方法的参数中。如:
public void doSomething(A<? extends List> a){
}
通过通配符声明的名称实例化的对象不能对其加入新的信息,只能获取或删除
泛型类型限制还可以使用super进行向上限制,如:
A<? super ArraytList> a = null;
- 因为一开始学这个有点懵,所以查了下资料,对上述限制泛型可用类型和使用类型通配符做了个认识和比较。
- 通配符使用通常是因为不知道接收端会传来什么类型的函数,因此设置的时候直接用 ? 代表接收任何类型的函数都行。
详情查看JAVA泛型与通配符详解
继承泛型类和实现泛型接口
- 定义为泛型的类和接口也可以被继承与实现。
- 定义的泛型接口也可以被实现。
泛型总结
使用方法:
- 泛型的类型参数只能是类类型,不可以是简单类型,如A这种泛型定义就是错误的。
- 泛型的类型个数可以是多个
- 可以使用extends关键字限制泛型的类型。
- 可以使用通配符限制泛型的类型。
实践与练习
- 定义一个泛型类,使用extends关键字限制该泛型类的类型为List接口,并分别创建两个反省对象。
- 尝试定义一个泛型类,并使用通配符。

1792

被折叠的 条评论
为什么被折叠?



