java新特性
1995.5.23 java语言1996 jdk1.0 250个类在API 主要用在桌面型应用程序
1997 jdk1.1 500 图形用户界面编程1998 jdk1.2 2300 J2SE J2EE J2ME2000 jdk1.3/1.42004 jdk1.5 3500 Teger语言2005 jdk1.62011 jdk1.7 java5新特性 自动装箱/拆箱 增强的for循环 类型安全枚举 可变长参数 静态导入 格式化输出 泛型 Annotation注解一、Autoboxing/Unboxing
------------------------------- 1.什么试装箱和拆箱? 装箱操作:将基本数据类型转换为它所对应的包装器类 拆箱操作:将包装器类转换为对应的基本数据类型包装器类:位于java.lang包下
8种基本数据类型 对应的包装器类 byte Byte short Short int Integer long Long char Character float Float double Double boolean Boolean 包装器类分为两类: 1.Number的子类: Byte Short Integer Long Charater Float Double 2.其他类型: Character BooleanNumber类:
intValue() doubleValue() ... *Value()用于返回该应用类型所代表的基本数据类型 2. 如何进行装箱和拆箱操作? Int a=10; Integer b=null; b=new Integer(a); //手动装箱 a=b.intValue(); //手动拆箱Boolean flag=true;//自动装箱 boolean flag1=flag;//自动拆箱 自动装箱/拆箱操作大大简化了基本数据类型和应用类型的使用
Integer i1=100;
Integer i2=100; if(i1==i2){ System.out.println("i1==i2"); }else{System.out.println("i1!=i2");} 存在的问题: 自动拆箱:调用*Value()方法,和手动拆箱相同 自动装箱:不是通过new的方法进行,通过调用valueof()方法 缓存池 Integer -127 ~128 Short -127 ~128 Long -127 ~128 Byte 全部缓存 Boolean 全部缓存 Float 都不缓存 Double 都不缓存 Charater 只缓存ASCII/Unicode编码<127的字符Enhanced for loop
-----------------------语法: for(type element:arr){ System.out.println(element); }type:类型,所要遍历的数组或集合里的数据类型
element:元素,遍历是的临时变量 arr:所要遍历的数组或集合的应用 集合必须实现了Iterable接口Collection ctrl+shift+oalt+/ 提示弊端:
1)增强的for循环本身无法明确的指向元素所在的索引位置 2)需要强制类型转换 三、 Type-safe enumeration 枚举类型---------------------------------------引入类型枚举可以控制源程序的非法值,只能是若干固定值的一个,如果超出这个范围,编译器在编译时报错。public class Gender{ private String name; private static final MALE=new Gender("男"); private static final FEMALE=new Gender("女"); private Gender(String name){ this.name=name; } public static Gender getInstance(int i){ switch(i){ case 0:return MALE; case 0:return FEMALE; default:return null; } }}Gender g1=new Gender("男");Gender g2=new Gender("女");
枚举类型的定义:
public enum Gender{ MALE,FEMALE;}其中每一个枚举元素都是该枚举类型的一个实例枚举的使用:
Gender male=Gender.MALE;Gender female=Gender.FEMALE;枚举的遍历
每个枚举类型默认都提供了两个静态方法values()和valueOf() for(Gender g:Gender.values()){} values()方法返回的是一个包含该枚举类型当中所有枚举元素的数组 valueOf(String name)可以通过枚举元素拿到该枚举类型的一个实例 Enum和enum的区别 1)每一个使用enum关键字定义的枚举类型默认都继承于java.lang.Enum类 2)枚举类当中的枚举元素都是该枚举类的实例,默认为public static final修饰的Enum类只有一个受保护的构造方法
protected Enum(String name,int ordinal){}name 代表枚举元素的名称ordinal代表枚举元素的编号,编号从0开始,按照声明顺序进行编号name() 获取该枚举元素的名称ordinal() 获取该枚举元素在列表中的编号 枚举类型的属性和方法枚举类中可以定义属性和方法规则:必须定义在枚举元素声明之后枚举类型的构造方法
1)构造方法必须定义在元素声明之后2)构造方法只能是private的,不写默认也是private的3)元素如果要调用有参构造方法,可以在元素之后加上“(参数)”枚举继承
枚举类型默认继承java.lang.Enum类,所以无法再继承其他类。枚举实现接口
有两种方法1)和普通class 类一样,在枚举类中实现接口2)每一个枚举元素分别实现这个接口枚举中的抽象方法
枚举类型中可以定义一个活多个抽象方法,但是每一个枚举元素必须分别实现这些抽象方法switch对枚举的支持
switch(byte)switch(int)switch(short)switch(char)switch(枚举类型) 类集对枚举的支持 java.util包下EnumMap 实现了Map接口,基本操作和Map相同 调用构造方法是,需要指定键值的枚举类型EnumSet 是想了Set接口 构造方法私有化 其中所有方法都是静态方法,可以通过allOf/of...方法来实例化EnumSet四、Variable Arguments可变长参数
------------------------------------ 可变长参数使得我们尅声明一个可接收可变数目参数的方法 public int sum(int a,int b){ return a+b; } public int sum(int a,int b,int c){ return a+b+c; } public int sum(int[] a){ //对数组进行遍历相加 //必须先声明一个数组}int[] a=new int[]{1,2,3,4};sum(a);------------------------public int sum(int...param){ //可变参数在处理的时候按照数组的方式进行处理 //不需要声明数组 //直接引用}sum(1,2);sum(2,3,4); 在使用可变参数后,在调用方法是可以依据类型传入一个或多个该类型的参数或传入一个该类型的数组参数使用条件:
//1)如果参数列表中有数组参数,不能再使用可变参数,两者不能够共存 2)在一个方法中最多只能定义一个可变参数,并且必须位于参数列表的最后 五、static import 静态导入----------------------------------- jdk1.5之前,要使用某个类的静态成员,必须给出提供该静态成员的类 jdk1.5引入静态导入:可以使被导入类的静态成员在当前类中直接可见,不需要再提供类名import static ......
过度使用会在一定程度上降低代码的可读性。
六、格式化输出(printf)
----------------------------------- java 中printf的语法比C语言中的要严格的多 java的格式输出有java.util.Formatter支持Formatter print风格的格式化字符串的解释程序 主要方法: format(String format,Object...rgs){} 第一个参数:包含格式化说明符的格式化字符串 第二个参数:与格式化说明符对应的可变参数 eg: format("this is %1$s,%d","test",100);格式化说明符的语法:
%[argument_index$][flags][width][.precision]conversionargument_index:代表参数在参数列表中的位置flags:标志位,用于表示输出格式 例如,“-”表示以左对齐方式输出width:表示参数所占用的宽度precision:表示整数位数或小数的浮点数conversion:具体的格式化字符日期格式化说明符语法:
%[argument_index$][flags][width]conversionconversion:t/TY tMString类和PrintStream类也支持格式化输出 String类增加了静态方法format(String format,Object...args) PrintStream类增加了printf(String format,Object...args) 七、Generic 泛型------------------------------------泛型的本质是参数化类型,也就是说我们所操作的数据类型可以被指定为一个参数,该参数可以用在类、接口和方法的创建中分别称为泛型类、泛型接口和泛型方法。意义:
jdk1.5之前,为了是类具有通用性,通常使用Object去代替其他类型。使用Object的缺陷: 1)需要进行强制类型转换; 2)容易出现ClassCastException通过引入泛型,可以保证编译时类型的安全和运行时更小的抛出ClassCastException异常的可能。 定义:泛型类:在声明类的时候,指定泛型类型参数 public class Test<T>{ private T foo; } 类型参数T可以是任意合法的标识符 一般约定: T type E element K key V value术语:
ArrayList<E> ArrayList称为该泛型类的原始类型 E为类型参数 <>读作typeof ArrayList<E>称为ArrayList的泛型类型/参数类型
使用:
在实例化泛型类时,只能传入具体的类类型,不能是基本数据类型。 泛型类中的属性类型可以根据传入的参数类型确定 不指定参数类型时,默认该类中的属性为Object 限制泛型的使用类别 当实例化泛型类时,预设可以使用任意类型去实例化泛型类型中的参数类型,但是如果要限制使用泛型类型时,只能是某个特定类型或其子类才能实例化该泛型类型,这时才可以使用extends关键字指定该参数类型是实现了某个接口或继承于某个类class Generic<T extends Number>{}
Generic<String> g=new Generic<String>();//program is faulsclass Generic<T extends Collection>{}
如果没有使用extends关键字指定类型是,默认是<T extends Object> 泛型通配声明 泛型通配符 ? Generic<String> foo=null; Generic<Integer> foo1=null; foo=new Generic<String>(); foo1=new Generic<Integer>();//声明
Generic<?> foo=null; foo=new Generic<String>(); foo=new Generic<Integer>(); ? 可以匹配任意的类型? extends 类型 表示该类型为某个特定的子类? super 类型 表示该类型为某个特定类型的父类 使用<?>或<? extends someClass>声明的引用,只能去获取指定对象的值或清空其值,而不能给他进行赋值操作 SimpleCollection int[] t; int index;add()
int getLength(); get(int i);泛型继承类别
public lass Chid<T> extends Parent<t>{}子类的类型声明必须和父类的一致public class Child extends Parent<String>{}
public class Child<T> extends Parent<String>{}泛型接口
使用和泛型类相同 语法定义: ingerface interName<类型参数,类型参数>{} eg: public interface Test<T>{ public abstract void fun(T t); public abstract T fun1(); }
泛型方法:
泛型方法的类型参数必须声明之后再能使用 1)在泛型类中,由于类型参数声明过,直接使用 2)在非泛型类中,需要在返回值前先声明类型参数才能使用
八、Annotation
--------------------------------------------------- jdk1.5引入Annotation,Annotation提供一些原来不属于源程序的数据,实际上表示的是一种注释语法,一种标记。根据所起的作用分为两类:编译检查:仅作为一个标记给编译器一些信息,让编译器在编译的时候做一些特殊的处理。代码处理:运行时通过反射可以获取annotation的信息并执行相应的操作(一)系统内建的Annotation
jdk1.5以后内建了三个annotation,他们都是用来做编译检查的 位于java.lang包下的annotation 1)@Override 表示重写/覆盖操作,强制保证@Override所标识的方法确实是覆盖了父类中的同名方法。 2)@Deprecated 表示过时的,不建议使用的操作 用法: a.定义了一个类,不建议使用它 b.在父类中定义了一个Deprecated的方法,子类重写时,编译器会发出警告。 3)@SuppressWarnings 表示抑制/压制警告,不让编译器发出警告,可以同时抑制多个警告 @SuppressWarnings({ "rawtypes", "unchecked", "deprecation" }) unchecked:表示未经检查的操作 deprecation:表示过时的操作 rawtypes:表示泛型 all:所有 @Override @Deprecated 是Marker Annotation, 即名称本身给编译器提供信息 @SuppressWarnings({ "rawtypes", "unchecked", "deprecation" })(二)自定义Annotation的定义和使用
自定义Annotation一般都是用来做代码处理的 语法定义: @Interface annotationName{ } public @Interface Override{ } 自定义的Annotation,本质上自动继承了java.lang.annotation.Annotation接口 Annotation与接口的异同: 1.Annotation是一个接口 1)变量和接口中的变量相同,只能是public static final的 2)方法和接口中一样,只能是public abstract的 2.Annotation是一个特殊的接口 1)annotation中的方法必须没有参数,不能抛出异常,必须有返回值,返回值类型有限制 2)可以给方法的返回值设定默认值 3)annotation中的方法称之为属性 4)使用的时候使用标记的形式使用 eg: @MyAnnotation 5)根据保留时间的不同执行不同的操作(高级特性)Annotation的属性
语法: type arrName()[default value]; type类型可以是: 基本数据类型 String类型 Class类类型 枚举类型 Annotation类型 以及它们的一维数组形式Annotation的使用
1.如果属性没有指定的默认值,使用是必须给属性赋值 2.如果只有一个属性且属性名称为value是,在使用时可以不指定属性名称。 3.除了value属性其他属性都有默认值时,在使用时也可以不指定属性名称。(三)高级特性---元注解
元注解:用来标识注解的注解 1.@Retention 用来指定annotation的保留范围,其取值有java.lang.annotation.RetentonPolicy提供 public enum RetentionPolicy{ SOURCE,//只保留在java源文件中 CLASS, //保留在class文件中,不会被JVM读取,默认 RUNTIME //保留在运行时(保留在class文件中,运行时被JVM读取) }@Retention(RetentionPolicy.CLASS)
public @interface myAnnotation{ } 一个自定义的annotation要想起作用,可以通过反射机制在运行时获取相应的信息。 java.lang.reflect.AnnotatedElement //用来判断指定元素上是否有指定类型的annotation存在 public abstract boolean isAnnotationPresent(Class AnnotationType) public abstract Annotation getAnnotation(Class annotationType) public abstract Annotation[] getAnnotations()2.@Target
用来指定annotation的使用范围,其取值有java.lang.annotation.ElementType提供 public @interface Target{ ElementType[] value(); } @Target({ElementType.METHOD,ElementType.FIELD}) public @interface myAnnotation{ } public enum ElementType{ ANNOTATION_TYPE,//annotation类声明上 CONSTRUCTOR, //构造器上 FIELD, //实例变量上 LOCAL_VARIABLE, //局部变量上 METHOD, //方法声明上 PACKAGE, //包声明上 PARAMETER, //参数声明上 TYPE //类,接口和枚举类型的声明上 } 对于PACKAGE的使用,必须是在package-info.java文件中使用 3.@Documented 使用@Documented所标记的annotation,在生成javadoc文档时会将annotation信息加入。 @Documented public @interface myAnnotation{ } 4.@Inherited 表示一个annotation是否会被使用该annotation的类的子类继承