一、枚举类型
1、使用枚举类型设置常量
其中,enum是定义枚举类型关键使用枚举类型定义常量的语法如下:
public enum Constants{
Constants_A,
Constants_B,
Constants_C
}
package bao;
interface Constants{
public static final int Constants_A=1;
public static final int Constants_B=12;
}
public class Demo1 { // 创建文件
enum Constants1{
Constants_A,Constants_B
}
//使用接口定义的常量
public static void doit(int c) {
switch(c) {
case Constants.Constants_A:
System.out.println("doit()Constants_A");
break;
case Constants.Constants_B:
System.out.println("doit()Constants_B");
break;
}
}
public static void doit2(Constants1 c) { //定义一个参数对象是枚举类型的方法
switch(c) { //根据枚举类型对象做不同的操作
case Constants_A:
System.out.println("doit2()Constants_A");
break;
case Constants_B:
System.out.println("doit2()Constants_B");
break;
}
}
public static void main(String[] args) {
Demo1.doit(Constants.Constants_A); //使用接口中的定义的常量
Demo1.doit2(Constants1.Constants_A); //使用枚举类型中的常量
Demo1.doit2(Constants1.Constants_B); //使用枚举类型中的常量
Demo1.doit(3);
}
}
/*
* 输出结果:
doit()Constants_A
doit2()Constants_A
doit2()Constants_B
* */
enum是定义枚举类型关键字。当需要在程序中使用该常量时,可以使用Constants.Constants_A来表示。
2、深入了解枚举类型
(操作枚举类型成员方法)
枚举类型较传统定义常量的方式,除了具有参数类型检测的优势之外,还具有其他方面的优势。 用户可以将一个枚举类型看作是一个类,它继承于java.lang.Enum类,当定义一个枚举类型时,每一个枚举类型成员都可以看作是枚举类型的一个实例,这些枚举类型成员默认都被final、public、static所修饰,所以当使用枚举类型成员时直接使用枚举类型名称调用枚举类型成员即可。
简单介绍主要的方法:
(1)values()
package bao;
public class Demo1 { // 创建文件
enum Constants{ //将常量放置在枚举类型中
ccc_A,ccc_B
}
public static void main(String[] args) {
for(int i=0;i<Constants.values().length;i++) { //循环有value()方法返回的数组
System.out.println("枚举类型成员变量:"+Constants.values()[i]); //将枚举成变量打印
}
}
}
/*
* 输出结果:
枚举类型成员变量:ccc_A
枚举类型成员变量:ccc_B
* */
(2)valueOf()与compareTo()
package bao;
public class Demo1 { // 创建文件
enum Constants{ //将常量放置在枚举类型中
ccc_A,ccc_B
}
public static void aaaccc(Constants c) {
for(int i=0;i<Constants.values().length;i++) { //循环有value()方法返回的数组
System.out.println(c+"与"+Constants.values()[i]+"的比较结果为:"+c.compareTo(Constants.values()[i])); //将比较结果返回
}
}
public static void main(String[] args) {
aaaccc(Constants.valueOf("ccc_B")); //在主方法中调用aaaccc()方法
}
}
/*
* 输出结果:
ccc_B与ccc_A的比较结果为:1
ccc_B与ccc_B的比较结果为:0
* */
(3)ordeinal()
package bao;
public class Demo1 { // 创建文件
enum Constants{ //将常量放置在枚举类型中
ccc_A,ccc_B,ccc_C
}
public static void main(String[] args) {
for(int i=0;i<Constants.values().length;i++) { //循环有value()方法返回的数组
System.out.println(Constants.values()[i]+"枚举类型中位置索引值"+Constants.values()[i].ordinal()); //将比较结果返回
}
}
}
/*
* 输出结果:
ccc_A枚举类型中位置索引值0
ccc_B枚举类型中位置索引值1
ccc_C枚举类型中位置索引值2
* */
(枚举类型中的构造方法)
枚举类型构造方法如:
enum 枚举类型名称{ //将常量放置在枚举类型中
ccc_A("枚举成员A"),
ccc_B("枚举成员B"),
ccc_C("枚举成员C"),
ccc_D(3);
private String descrption;
private Constants2() { //定义默认构造函数
}
private Constants2(String descrption) { //定义带参数的构造方法,参数类型为字符串类型
this.descrption=descrption;
}
private Constants2(int i) { //定义带参数的构造方法,参数类型为整形
this.descrption=this.i+i;
}
}
例子如下:
package bao;
import static java.lang.System.out;
public class Demo1 { // 创建文件
enum Constants2{ //将常量放置在枚举类型中
ccc_A("枚举成员A"),
ccc_B("枚举成员B"),
ccc_C("枚举成员C"),
ccc_D(3);
private String descrption;
private int i=4;
private Constants2() { //定义默认构造函数
}
private Constants2(String descrption) { //定义带参数的构造方法,参数类型为字符串类型
this.descrption=descrption;
}
private Constants2(int i) { //定义带参数的构造方法,参数类型为整形
this.i=this.i + i;
}
public String getDescrption() { //获取 getDescrption的值
return descrption;
}
public int getl() { //获取i的取值
return i;
}
}
public static void main(String[] args) {
for(int i=0;i<Constants2.values().length;i++) {
out.println(Constants2.values()[i]+"调用getDescrption()方法为:"+Constants2.values()[i].getDescrption());
}
out.println(Constants2.valueOf("ccc_D")+"调用getl()方法为:"+Constants2.valueOf("ccc_D").getl());
}
}
/*
* 输出结果:
ccc_A调用getDescrption()方法为:枚举成员A
ccc_B调用getDescrption()方法为:枚举成员B
ccc_C调用getDescrption()方法为:枚举成员C
ccc_D调用getDescrption()方法为:null
ccc_D调用getl()方法为:7
* */
3、使用枚举类型的优势
枚举类型声明提供了一种用户友好的变量定义方法,枚举了某种数据类型所有可能出现的值。总结枚举类型,它具有以下特点:
- 类型安全。
- 紧凑有效的数据定义。
- 可以和程序其他部分完美交互。
- 运行效率高。
二、泛型
1、回顾“向上转型”与“向下转型”
向上转型:
父类 a=new 子类();
向下转型:
子类 b=(子类)a;
a代表父:父类 a=new 子类();
例子如下:
package bao;
public class Demo1 { // 创建文件
private Object a;
public Object getB() { //设置get()方法
return a;
}
public void setB(Object a) { //设置set()方法
this.a=a;
}
public static void main(String[] args) {
Demo1 t=new Demo1();
t.setB(new Boolean(true)); //向上转型
System.out.println(t.getB());
t.setB(new Float(12.3));
Float f=(Float)(t.getB()); //向下转型
System.out.println(f);
}
}
/*
* 输出结果:
true
12.3
* */
2、定义泛型类
Object类为最上层的父类,很多程序员为了使程序更为通用,设计程序时通常使传入的值与返回的值都以Object类型为主。当需要使用这些实例时,必须正确地将该实例转换为原来的类型,否则在运行时将会发生ClassCastException异常。 在JDK 1.5版本以后,提出了泛型机制。
其语法如下: 类名<T> 其中,T代表一个类型的名称。
类名<T>
package bao;
public class Demo1<T> { // 创建文件
private T a;
public T getB() { //设置get()方法
return a;
}
public void setB(T a) { //设置set()方法
this.a=a;
}
public static void main(String[] args) {
Demo1<Boolean> b=new Demo1<Boolean>(); //实例化Boolean对象
Demo1<Float> f=new Demo1<Float>(); //实例化Float对象
b.setB(true); //不需要进行类型转换
f.setB(12.3f);
Boolean bool=b.getB(); //不需要进行类型转换
Float floa=f.getB();
System.out.println(b);
System.out.println(f);
}
}
/*
* 输出结果:
bao.Demo1@1175e2db
bao.Demo1@36aa7bc2
* */
3、泛型的常规用法
(1)定义泛型类时声明多个类型
MutiOverClass<T1,T2>
MutiOverClass;泛型类型
例子:
MutiOverClass<Boolean,Float>=new MutiOverClass<Boolean,Float>();
(2)定义泛型类时声明数组类型
package bao;
public class Demo1<T> { // 创建文件
private T[]array;
public void SetB(T[] array) { //设置Set()方法
this.array=array;
}
public T[] getB() { //设置get()方法
return array;
}
public static void main(String[] args) {
Demo1<String> a=new Demo1<String>();
String[] array= {"成员1","成员2","成员3","成员4","成员5"};
a.SetB(array);
for(int i=0;i<a.getB().length;i++) {
System.out.println(a.getB()[i]);
}
}
}
/*
* 输出结果:
成员1
成员2
成员3
成员4
成员5
* */
(3)集合类声明容器的元素
使用K,V两个字符代表容器中的键值和与键值相对应的具体值。
package bao;
import java.util.HashMap;
import java.util.Map;
public class Demo1<K,V> { // 创建文件
public Map<K,V> m=new HashMap<K,V>(); //定义集合HashMap实例
//设置put()方法,将对应的键值与键名唇乳集合对象中。
public void put(K k,V v) {
m.put(k, v);
}
public V get(K k) { //根据键名获取键值
return m.get(k);
}
public static void main(String[] args) {
Demo1<Integer,String>mu=new Demo1<Integer,String>(); //实例化泛型对象
for(int i=0;i<5;i++) {
mu.put(i, "我是集合成员"+i); //根据集合的长度循环将键名与具体值放入集合中
}
for(int i=0;i<mu.m.size();i++) {
System.out.println(mu.get(i)); //调用get()方法获取集合中的值
}
}
}
/*
* 输出结果:
我是集合成员0
我是集合成员1
我是集合成员2
我是集合成员3
我是集合成员4
* */
常用的被泛型化的集合类
集合类 | 泛型定义 |
ArrayList | ArrayList<E> |
HashMap | HashMap<K,V> |
HashSet | HashSet<E> |
Vector | Vector<E> |
4、泛型的高级用法
(1)限制泛型可用类型
默认可以使用任何类型进行实例一个泛型类对象,但Java中也对泛型类实例类型做了限制。
class 类名称<T extends anyClass>
anyClass:某接口或某类。
例子:
package bao;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class Demo1<T extends List> { // 创建文件
public static void main(String[] args) {
Demo1<ArrayList> l1=new Demo1<ArrayList>();
Demo1<LinkedList> l2=new Demo1<LinkedList>();
}
}
(2)使用类型通配符
限制这个泛型类的类型实现或继承某个接口或类的子类。
泛型类名称<? extends List>a=null;
(3)继承泛型类与实现泛型接口
继承泛型类:
public class ExtendClass<T1>{
}
class SubClass<T1,T2,T3>extends ExtendClass<T1>{
}
实现泛型接口:
interface i<T1>{
}
class SubClass<T1,T2,T3>implements i<T1>{
}
5、泛型总结
- 下面总结一下泛型的使用方法。 泛型的类型参数只能是类类型,不可以是简单类型,如A<int>这种泛型定义就是错误的。 (Demo<Integer>)
- 泛型的类型个数可以是多个 。 (Demo<T,K,V>)
- 可以使用extends关键字限制泛型的类型。 (Demo<T extends Number>)
- 可以使用通配符限制泛型的类型。 (Demo<?>)