目录
枚举类型?
?深入枚举类型
1.values()方法
2.valueOf()方法和compareTo()方法?
枚举类型的优势
泛型
定义泛型类
定义泛型时声明多个类型
定义泛型数组
泛型方法?
?泛型的高级用法
通配符的超类型限定?
继承泛型类
实现泛型接口
总结
?
枚举类型?
常规定义常量的代码如下:
public interface Constants{
public static final int Constants_A=1;
public static final int Constants_B=2;
}
?枚举类型出现后,逐渐取代了上述常量定义方式。
public enum Constants{
Constants_A,
Constants_B,
}
enum是定义枚举类型的关键字。当需要在程序中使用该变量时,可以使用Constants.Constants_A来表示
enum season{
spring,
summer,
autumn,
winter
}
public class test {
public static void season1(season s)
{
switch(s){
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)
{
season1(season.spring);
season1(season.summer);
season1(season.autumn);
season1(season.winter);
}
}
?
?深入枚举类型
枚举类型较传统定义常量的方式,除具有参数类型检测的优势外,还具有其他方面的优势。
用户可以将一个枚举类型看做是一个类,它继承于java.lang.Enum类,当定义一个枚举类型时,每一个枚举类型成员都可以看做是枚举类型的一个实例,这些枚举类型成员都默认被final,public,static修饰,所以当使用枚举类型成员时直接使用枚举类型名称调用枚举类型成员即可。
方法 | 含义 | 使用方法 | 举例 | values() | 该方法可以将枚举类型成员以数组的形式返回 | 枚举类型名称.values() | Constants2.values() | valueOf() | 该方法可以实现将普通字符串转换为枚举实例 | 枚举类型名称.valueOf() | Constants2.valueOf("ab") | compareTo() | 该方法用于比较两个枚举对象在定义时的顺序 | 枚举对象.compareTo() | Constants_A.compareTo (Constants_B) | ordinal() | 该方法用于得到枚举成员的位置索引 | 枚举对象.ordinal() | Constants_A.ordinal() |
1.values()方法
enum season{
spring,
summer,
autumn,
winter
}
public class test {
public static void main(String[] args)
{
season a[]=season.values();
for(int i=0;i<a.length;i++)
{
System.out.println("枚举:"+a[i]);
}
}
}
2.valueOf()方法和compareTo()方法?
枚举类型中静态方法valueOf()可以将普通字符串转换为枚举类型,而compareTo()方法用于比较两个枚举类型对象定义时的顺序
enum season{
spring,
summer,
autumn,
winter
}
public class test {
public static void main(String[] args)
{
season t=season.valueOf("summer");//创建一个枚举值
season a[]=season.values();//获取所有枚举值
for(int i=0;i<a.length;i++)
{
String m="";
int result=t.compareTo(a[i]);
if(result<0)
{
m=t+"在"+a[i]+"的前"+(-result)+"个位置";
}else if(result>0)
{
m=t+"在"+a[i]+"的后"+result+"个位置";
}else if(result==0)
{
m=t+"与"+a[i]+"是同一个值";
}
System.out.println(m);
}
}
}
3.ordinal()方法?
枚举类型中的ordinal()方法用于获取某个枚举对象的位置索引值
enum season{
spring,
summer,
autumn,
winter
}
public class test {
public static void main(String[] args)
{
season a[]=season.values();
for(int i=0;i<a.length;i++)
{
System.out.println(a[i]+"位置索引值为"+a[i].ordinal());
}
}
}
?4.枚举类型中的构造方法
构造方法必须被private修饰符所修饰
enum season{
spring("春季"),
summer("夏季"),
autumn("秋季"),
winter("冬季");
private String str;//枚举的备注()
private season(String str)//构造方法
{
this.str="我来自"+this.toString()+str;
}
public String getstr()//get,获取备注
{
return str;
}
}
public class test {
public static void main(String[] args)
{
season a[]=season.values();
for(int i=0;i<a.length;i++)
{
System.out.println(a[i].getstr());
}
}
}
枚举类型的优势
笔记:?
- ?类型安全
- 紧凑有效的数据定义
- 可以和程序其他部分完美交互
- 运行效率高
泛型
泛型意味着编写的代码可以被很多不同类型的对象所重用。泛型实质上就是使程序员定义安全的类型。某些强制类型转换的错误也许不会被编译器捕捉,而在运行后出现异常,可见强制类型转换存在安全隐患,所以在此提供了泛型机制。
public class test {
private Object a;
public Object geta()
{
return a;
}
public void seta(Object a)
{
this.a=a;
}
public static void main(String[] args)
{
test t=new test();
t.seta(Float.valueOf("10.1"));
Integer b=(Integer)t.geta();
System.out.println(b);
}
}
该段代码并不存在语法错误,但是在执行时会出现ClassCastException异常
?这就需要泛型机制了
定义泛型类
语法如下:
类名<T>
其中,T是泛型的名称,代表某一种类型。开发者在创建该类对象时需要指定T所代表哪种具体的类型。如果不指定具体类型,T则采用Object类型(Object类为最上层的父类)
public class test<T> {
private T studytest;
public test(T studytest)
{
this.studytest=studytest;
}
public T getstudytest()
{
return studytest;
}
public static void main(String[] args)
{
//创建参数为String类型的对象
test<String> studyname=new test<String>("小王");
//创建参数为Double类型的数值对象
test<Double> studytime=new test<Double>(10.2);
System.out.println("名字:"+studyname.getstudytest());
System.out.println("学习时长:"+studytime.getstudytest());
}
}
使用泛型这种形式将不会发生ClassCastException异常,因为在编译器中就可以检查类型匹配是否正确
定义泛型时声明多个类型
class M<T1,T2>{ }
这样在实例化指定类型的对象时就可以指定多个类型
例如
M <Double,Float> m=new M<Double,Float>();
定义泛型数组
public class test<T> {
private T[] a;
public void seta(T[] a)
{
this.a=a;
}
public T[] geta()
{
return a;
}
public static void main(String[] args)
{
test<String>A=new test<String>();
String B[] = {"一号选手","二号选手","三号选手","四号选手"};
A.seta(B);
String C[]=A.geta();
for(int i=0;i<C.length;i++)
{
System.out.println(C[i]);
}
}
}
注意:可以在使用泛型机制时声明一个数组,但是不可以使用泛型来建立数组的实例?
泛型方法?
public class test<T> {
public static <T> T geta(T...a)
{
return a[a.length-1];
}
public static void main(String[] args)
{
String B=test.<String>geta("abc","SJKA","skfal");
System.out.println(B);
}
}
也有个点注意一下
编译器会自动打包参数为1个Double和2个Integer对象,而后寻找这些类的共同超类型。事实上,找到2个这样的超类型:Number和Comparable接口,其本身也是一个泛型类型,我们将参数都写成Double值就可以了?
?泛型的高级用法
1.限制泛型可用类型
class 类名<T extends anyClass>
其中,anyClass指某个接口或类。使用泛型限制后,泛型类的类型必须实现或继承anyClass这个接口或类。无论anyClass是接口还是类,在进行泛型限制时都必须使用extends关键字。
举例如下?
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;
public class test<T extends List> {
public static void main(String[] args)
{
test<ArrayList>a1=new test<ArrayList>();
test<LinkedList>a2=new test<LinkedList>();
}
}
2.使用类型通配符
在泛型机制中,提供了类型通配符,其主要作用是在创建一个泛型类对象时限制这个泛型类的类型实现或继承某个接口或类的子类。要声明这样一个对象可以使用"?"通配符来表示,同时使用extends关键字来对泛型加以限制。
泛型类名称<?extends List>a=null;
例如
a=new A<ArrayList>();
a=new A<LinkedList>();
public void TEST(A<?extends List>a){}
定义方式有效地限制了传入TEST()方法的参数类型
import java.util.List;
import java.util.ArrayList;
public class test<T extends List> {
public static void main(String[] args)
{
List<String>a1=new ArrayList<String>();
a1.add("小明");
List<?>a2=a1;
System.out.println(a2.get(0));
}
}
?注意:使用通配符声明的名称实例化的对象不能对其加入新的信息,只能获取或删除(无法调用set()方法改变集合中的值)
通配符的超类型限定?
?super Manger
这个通配符限制为Manger的所有超类型
在 Pair<?super Manger>有方法?
void setfirst(?super Manger)
?super Manger getfirst()
编译器不知道setfirst的确切类型,但是可以用任意Manger对象(或子类型)调用它。然而调用getfirst,返回的对象类型不会得到保证
继承泛型类
class A<T1>{}
class B<T1,T2,T3>extends A<T1>{}
如果在B类继承A类时保留父类的泛型类型,需要在继承时指明
实现泛型接口
interface S<T1>{}
class A<T1,T2,T3>implements S<T1>{}
总结
视频笔记:
- 泛型的类型参数只能是类类型,不可以是简单类型,如A<int>则错误
- 泛型的类型个数可以是多个
- 可以使用extends关键字限制泛型的类型
- 可以使用通配符限制泛型的类型
- 泛型不同的引用不能相互赋值
- 泛型如果不指定,将被擦除,泛型对应的类型均按照Object处理,但不等价于Object.
- 泛型要使用一路都用,要不使用,一路都不用
- JDK1.7,泛型的简化操作:ArrayList<Fruit>flist =new ArrayList<>();
- 泛型指定中虽然不能用基本数据,但能用包装类替换
- 静态方法中不能使用类的泛型
- 异常类是不能泛型的
- 不能使用new E[].但是可以:E[] elements=(E[])new Object[capacity];
- 父类有泛型,子类可以选择保留泛型,也可以选择指定泛型。不保留——没有类型则擦除||具体类型。保留——全部保留||部分保留
- 子类还可以增加自己的泛型
学习如逆水行舟,不进则退。和小吴一起加油吧!
|