Hi java新特性
java新特性
1995.5.23    java语言
1996    jdk1.0    250个类在API   主要用在桌面型应用程序
1997    jdk1.1    500            图形用户界面编程
1998    jdk1.2    2300           J2SE  J2EE J2ME
2000    jdk1.3/1.4
2004    jdk1.5    3500           Teger语言
2005    jdk1.6
2011    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  Boolean
Number类:
   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+o
alt+/   提示
弊端:
   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]conversion
argument_index:代表参数在参数列表中的位置
flags:标志位,用于表示输出格式     例如,“-”表示以左对齐方式输出
width:表示参数所占用的宽度
precision:表示整数位数或小数的浮点数
conversion:具体的格式化字符
    日期格式化说明符语法:
		 %[argument_index$][flags][width]conversion
conversion:t/TY  tM
  
String类和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 fauls
	class 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的类的子类继承
你要坚强,坚强的足以认识自己的弱点;你要勇敢,勇敢的足以面对自己的恐惧;你要堂堂正正。在遇到挫折时能够昂首而不背躬屈膝;你要能够面对掌声,在胜利时能够谦逊而不趾高气扬。真正的伟大直率真诚,真正的贤人虚怀若谷,真正的强者温文尔雅。——萨利·布什(林肯的继母教育林肯)
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号