17枚举类型与泛型
17.1枚举类型
17.1.1使用枚举类型设置常量
-
package com.reflect; interface Constants{ public static final int Constants_A=1; public static final int Constants_B=12; } public class ConstantsTest { enum Constants2{//将常量放在枚举类型中,enum是定义枚举类型的关键字 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(Constants2 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) { ConstantsTest.doit(Constants.Constants_A); ConstantsTest.doit2(Constants2.Constants_A); ConstantsTest.doit2(Constants2.Constants_B); ConstantsTest.doit(3); //ConstantsTest.doit2(3); } }
17.1.2深入了解枚举类型
-
操作枚举类型成员的方法
-
values()
-
package com.reflect; public class ShowEnum { enum Constants2{ Constants_A, Constants_B; } public static void main(String[] args) { for(int i=0;i<Constants2.values().length;i++){ System.out.println("枚举类型成员变量:"+Constants2.values()[i]); } } }
-
-
valueOf()
-
compareTo()
-
package com.reflect; public class EnumMethodTest { enum Constants2{ Constants_A, Constants_B; } public static void compare(Constants2 c){ for(int i = 0; i< ShowEnum.Constants2.values().length; i++){ System.out.println(c+"与"+Constants2.values()[i]+"的比较结果为:"+c.compareTo(Constants2.values()[i])); } } public static void main(String[] args) { compare(Constants2.valueOf("Constants_B")); } }
- 在调用compareTo()方法返回结果中,正值代表方法中参数在调用该方法的枚举对象前,0则表示位置相同,负值表示参数在调用该方法的枚举对象后。
-
-
ordinal()
-
package com.reflect; public class EnumindexTest { enum Constants2{ Constants_A, Constants_B, Constants_C; } public static void main(String[] args) { for(int i = 0; i< EnumindexTest.Constants2.values().length; i++){ System.out.println(Constants2.values()[i]+"在枚举类型中位置索引值"+Constants2.values()[i].ordinal()); } } }
-
-
-
枚举类型中的构造方法
-
在枚举类型中可以添加构造方法,但必须是private类型
-
package com.reflect; public class CopyOfEnumIndexTest { enum Constants2{ Constants_A("我是枚举成员A"), Constants_B("我是枚举成员B"), Constants_C("我是枚举成员C"), Constants_D(3); private int i=4; private String description; private Constants2(){ } private Constants2(String description){ this.description=description; } private Constants2(int i){ this.i=this.i+i; } public String getDescription(){ return description; } public int getI(){ return i; } } public static void main(String[] args) { for(int i=0;i<Constants2.values().length;i++){ System.out.println(Constants2.values()[i]+"调用getDescription()方法为:"+Constants2.values()[i].getDescription()); System.out.println(Constants2.valueOf("Constants_D")+"调用getI()方法为:"+Constants2.valueOf("Constants_D").getI()); } } }
-
将构造方法设置为private休息,以防实例化枚举对象
-
package com.reflect; 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++){ System.out.println(AnyEnum.values()[i]+"getDescription()方法为:"+AnyEnum.values()[i].getDescription()); System.out.println(AnyEnum.values()[i]+"getI()方法为:"+AnyEnum.values()[i].getI()); } } }
-
-
17.1.3使用枚举类型的优势
- 类型安全
- 紧凑有效的数据定义
- 可以和程序其他部分完美交互
- 运行效率高
17.2泛型
17.2.1回顾”向上转型“和”向下转型“
-
package com.FanXing; public class Test { private Object b; public Object getB(){ return b; } public void setB(Object b){ this.b=b; } public static void main(String[] args) { Test t= new Test(); 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); } }
17.2.2定义泛型类
-
泛型机制:类名,T代表一个类型的名称
-
将上例改写,定义类时使用泛型形式
-
package com.FanXing;
-
public class OverClass {//定义泛型类
private T over;//定义泛型成员变量
public T getOver(){//设置getXXX()方法
return over;
}
public void setOver(T over){
this.over=over;
}
public static void main(String[] args) {
//实例化一个Boolean型的对象
OverClass over1=new OverClass();
//实例化一个Float型的对象
OverClass over2=new OverClass();
over1.setOver(true);//不需要进行类型转换
over2.setOver(12.3f);
Boolean b=over1.getOver();//不需要进行类型转换
Float f=over2.getOver();
System.out.println(b);
System.out.println(f);
}
}
```
- 使用泛型定义的类在声明该类对象时可以根据不同的需求指定真正的类型,而在使用类中的方法传递或返回数据类型时将不再需要进行类型转换操作,而是使用在声明泛型类对象时<>符号中设置的数据类型。
17.2.3泛型的常规用法
-
定义泛型类时声明多个类型
-
MutiOverClass<T1,T2> MutiOverClass<Boolean,Float>=MutiOverClass<Boolean,Float>();
-
定义泛型类时声明数组类型
-
package com.FanXing; 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[] array={"成员1","成员2","成员3","成员4","成员5"}; a.SetT(array); for(int i=0;i<a.getT().length;i++){ System.out.println(a.getT()[i]); } } }
可以用泛型机制声明一个数组,但不可以使用泛型机制建立数组的实例
//private T[] array=new [10];//错误
-
-
集合类声明容器的元素
package com.FanXing; import java.util.HashMap; import java.util.Map; public class MutiOverClass<K,V> { public Map<K,V> m=new HashMap<K,V>();//定义一个集合HashMap实例 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) { //实例化泛型对象 MutiOverClass<Integer,String> mu= new MutiOverClass<Integer, String>(); for(int i=0;i<5;i++){ //根据集合的长度循环将键值与具体值放入集合中 mu.put(i,"我是集合成员"+i); } for(int i=0;i<mu.m.size();i++){//HashMap是泛型类的一个方法,调用此方法,获得HashMap长度 System.out.println(mu.get(i)); } } }
-
在java中,一些集合框架已经被泛型化,可以在主方法中直接使用public Map<K,V> m=new HashMap<K,V>();语句创建实例,然后调用相应的Map接口中的put()与get()方法完成填充容器或根据键值获取具体值的功能。
-
也就是说,在java中已经将HashMap ArrayList HashSet Vector定义为泛型类,主方法中直接实例化就好。
-
package com.FanXing; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Vector; public class AnyClass { public static void main(String[] args) { ArrayList<Integer> a=new ArrayList<>(); a.add(21); for(int i=0;i<a.size();i++) { System.out.println("获取ArrayList容器的值"+a.get(i)); } 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> v=new Vector<String>(); for(int i=0;i<5;i++) { v.addElement("成员"+i); } for(int i=0;i<v.size();i++) { System.out.println("获取Vector容器的值"+v.get(i)); } } }
-
-
17.2.4泛型的高级用法
-
限制泛型可用类型
-
class 类名称<T extends anyClass>
-
package com.FanXing; import java.util.*; import java.util.ArrayList; import java.util.LinkedList; public class LimitClass<T extends List> {//限制泛型的类型 public static void main(String[] args) { LimitClass<ArrayList> L1=new LimitClass<ArrayList>(); LimitClass<LinkedList> L2=new LimitClass<LinkedList>(); //LimitClass<HashMap> L3=new LimitClass<HashMap>(); } }
-
-
使用类型通配符
-
作用:在创建一个泛型类对象时限制这个泛型类的类型实现或继承某个接口或类的子类。
-
package com.FanXing; import java.util.ArrayList; import java.util.LinkedList; public class Test_05{ public static void main(String[] args) { ArrayList<String> l1=new ArrayList<String>(); l1.add("成员"); ArrayList<?> l2=l1; ArrayList<?> l3=new ArrayList<Integer>(); System.out.println(l2.get(0)); l1.set(0,"成员改变");//没有使用对象通配符的对象调用set()方法 //l2.set(0,"成员改变");//使用通配符的对象调用set()方法,不能被调用 //l2.set(0,1); l2.get(0);//可以使用l2的实例获取集合中的值 l2.remove(0);//根据键值删除集合中的值 } }
-
注意:使用通配符声明的名称实例化的对象不能对其加入新的信息,只能获取或删除。
-
使用A<? super List> a=null;这样对象a只接受List接口或上层父类类型
-
-
继承泛型类与实现泛型皆苦
-
定义为泛型的类和接口也可以被继承与实现
-
public class ExtendClass<T1>{ //... } class subClass<T1,T2> extend ExtendClass<T1>{ //.. } //如果subClass类继承ExtendClass类时保留父类的泛型类型需要在继承时声明。 //不指明则T1,T2,T3都会自动编程Object
-
interface i<T1>{ //... } class SubClass2<T1,T2,T3> implements i<T1>{ //... }
-
-
17.2.5泛型总结
- 泛型的类型参数只能时类 类型,不可以是简单类型。 A错误
- 泛型的类型参数个数可以是多个
- 可以使用extends关键字限制泛型的类型
- 可以使用通配符限制泛型的类型