Java新特性(一)
重点:泛型,枚举,Annotation
可变参数
不确定要传递的参数个数
以前将多个参数封装成数组
JDK1.5在方法定义上提供了可变参数的概念
[public|protected|private] [static] [final] [abstract] 返回值类型 方法名称[参数类型... 变量]{
[return [返回值];]
}
卡发着可以使用参数类型…变量形似传递若干个参数
多个参数变量传递到方法中以指定类型的数组进行保存
传递时是多个参数,但是接收后就变成了一个数组的内容
目前开发中已经大量使用了可变参数
public class Test {
public static void main(String args[]){
System.out.println(add(1,2,3,4));
}
public static int add(int... data){ //最后还是以数组形式处理接受的参数
int sum = 0;
for (int x =0;x<data.length;x++){
sum = data[x];
}
return sum;
}
}
foreach循环
foreach是一种加强型for循环
主要可以用来简化数组或者集合的输出操作
不用去管索引
for(数据类型 变量:数组|集合)
类似于迭代器
静态导入
如果某个类中的定义方法全部属于static型方法,其他类引用此类时必须使用import导入所需要的包
以前直接用import导入时,使用方法要在前面加上类名
如果使用静态导入import static 类名
在程序中只要使用方法名就可以直接调用,不用类名称
泛型
java中向下转型是不安全的,可能存在异常
JDK1.5提供了泛型技术解决了这个问题
以往使用自动装箱拆箱实现数据传输需要向上转型和向下转型
使用Object接收参数存在安全隐患,因为手动向上转型向下转型必须明确参数类型
假如参数类型不匹配会在运行时出现异常
使用泛型解决这个问题:
这个技术的意义在于:类属性或者方法的参数在定义数据类型时可以直接使用一个标记进行占位,在具体使用时才设置其对应的实际数据类型
以往的Object类进行转型时,如果出现类型转换错误在编译阶段不会报错,运行才会出异常、
使用泛型可以在编译阶段提前发现错误
package generic;
public class Point<T> { //此时不知道T的属性,在使用时动态确定
private T X;
private T Y;
public void setX(T X){
this.X = X;
}
public void setY(T Y){
this.Y=Y;
}
public Object getX(){
return X;
}
public Object getY(){
return Y;
}
}
public class Test {
public static void main(String args[]){
Point<String> point = new Point<String>();
point.setX("1");
point.setY("2");
String X = point.getX();
String Y = point.getY();
System.out.println(X+Y);
}
}
在使用过程中,定义Point对象要明确写出T代表什么
开发中可以定义多个泛型声明
class Point<P,R>{
public R fun(P p){
return null
}
}//P是参数类型,R是返回值类型
想使用泛型,能够采用的类型只能是类,即引用类型,不能是基本类型,基本类型还还是要装箱
<引用类型>,尖括号里的标记类型是引用类型
如果不给用泛型声明的类加入泛型标记,那么就默认使用Object类
JDK1.7以后,只要在对象声明中使用了泛型就不用再重复设置泛型类型
实际开发中尽量使用泛型而不是Object类
通配符
泛型解决了向下转型的安全隐患,但是同一个类如果泛型类型不同就不能直接进行引用操作
会在参数传递上产生新的问题
即参数虽然是同类,但是因为标记的泛型不同而无法传递
方法重构在不能解决这个问题
方法的参数只对类进行区分而不会对泛型进行区分
使用通配符"?"进行描述可以解决这个问题
在定义以泛型为参数的方法时可以使用通配符"?"
public static void(Point<?> temp){}
只要是该类对象不管泛型是啥都可以接受
不可以使用Point描述一切泛型
虽然Object是一切的父类
但是在作为泛型标记中不讲继承关系
所以Piont和Point完全独立
如果不设泛型又会直接使用Object类导致安全隐患
故在定义方法时建议使用通配符<?>
通配符<?>能接受类的对象而不更改对象的属性,只能从对象取出数据而不能修改数据
Object类可以随意修改属性内容,即使类型不匹配也可以强行修改,从而出现类型转换异常
通配符的子通配符
?extends 类:设置泛型上限在声明和方法参数上使用
?extends Number意味着只能使用Number或者其子类
?super 类:设置泛型下限,方法参数上使用
?super String只能使用String或其父类
泛型接口
泛型不仅可以定义在类上,还可以定义在接口上,即泛型接口
实现方法
-
在子类中继续设置泛型标记
interface IMessage<T>{ //泛型接口 publicvoid print(T t); } class MessageImpl<S> implements IMessage<S>{ //子类也设置泛型 public void print(S t){ System.out.println(t); } } public class Test{ public static void main(String args[]){ IMessage<String> msg = new MessageImpl<String>(); msg.print("WDNMD") } }
-
子类不设置泛型,父类明确定义泛型类型
interface IMessage<T>{ //泛型接口 publicvoid print(T t); } class MessageImpl implements IMessage<String>{//直接设置类型 public void print(String t){ System.out.println(t); } } public class Test{ public static void main(String args[]){ IMessage<String> msg = new MessageImpl();//没有泛型直接用,实例化不需要设置泛型 msg.print("WDNMD") } }
泛型方法
方法中也可以定义泛型,泛型方法不一定要定义在泛型类中
public static <T> T fun(T t){ return t;}
即只有方法声明出现泛型标记
这样就可以在参数类型和返回值类型上使用泛型