JAVA5新特性

JAVA5新特性
                    
1>Java在逐渐与C++融合
2>五小点,四大点

一、五小点

 

1、自动封箱AutoBoxing/自动解封
   自动封箱和自动拆箱,它实现了简单类型和封装类型的相互转化时,实现了自动转化。 
    byte b     -128~127
    Byte b     在以上数量的基础上多一个null

   简单类型和封装类型之间的差别
   封装类可以等于null  ,避免数字得0时的二义性。
   Integer i=null;
   int ii=i;  //会抛出NullException 异常。相当于 int ii=i.intValue();
   Integer i=1; //相当于Integer i=new Integer(1);
   i++;    // i = new Integer(i.intValue()+1);

   在基本数据类型和封装类之间的自动转换
   5.0之前
   Integer i=new Integer(4);
   int  ii= i.intValue();

   5.0之后
   Integer i=4;
   Long l=4.3;
  
   public void m(int i){......}
   public void m(Integer i){......}
   以上两个函数也叫方法重载
   自动封箱解箱只在必要的时候才进行。能不封箱找到匹配的就不封箱。
  
   注意:Integer 和 int 的默认值是不一样的,Integer 是null(对象嘛),int 是0(基本数据类型嘛);

 

2、静态引入 StaticImport
   使用类中静态方法时不用写类名
  
   System.out.println(Math.round(PI));
   可以用以下代码实现:
   import static java.lang.System.*;  //注意,要写" 类名.* "
   import static java.lang.Math.*;
   out.println(round(PI));
  
   注意:静态引入的方法不能重名
  
3、for-each
   统一了遍历  数组  和遍历  集合  的方式  
   for(Object o:list){     //Object o 表示每个元素的类型 ,list 表示要遍历的数组或集合的名字
       System.out.println(o);  //打印集合或数组中的每个元素
   }


4、可变长参数
   处理方法重载中,参数类型相同,个数不同的情况     
   public void m(int... is){.....}
  
   int... is 相当于一个 int[] is
   编译器会把给定的参数封装到一个数组中,再传给方法
   在一个方法中只能有一个可变长参数,而且,必须放在最后一个参数的位置
  
5、格式化输入/输出
   java.util.Formatter类 对格式的描述
   System.out.printf("Hello %s",str);  //打印字符串类型的变量,用一个占位符  
  
   格式化I/O(Formatted I/O)
   java.util.Sacner类可以进行格式化的输入,可以使用控制台输入,结合了BufferedReader和StringTokener的功能。
  


二、四大点  

 

1、枚举(Enum)
  枚举是一个类,并且这个类的对象是现成的,在定义类的时候,即定义好了对象
  程序员要使用的时候,只能从中选择,无权创建
  enum 枚举名{
 枚举值1(..),枚举值2(..),.....;
  }
 
(1) 在5.0之前使用模式做出一个面向对象的枚举
    final class Season{
        public static final Season SPRING=new Season();
        public static final Season WINTER=new Season();
        public static final Season SUMMER=new Season();
        public static final Season AUTUMN=new Season();
        private Season(){}
    }
    完全等价于
    enum Season2{
 SPRING(..),//枚举值
 SUMMER(..),
 AUTUMN(..),
 WINTER(..)
    }     
 
    枚举本质上也是一个类,Enum是枚举的父类。
    这个类编译以后生成一个.class类
    这个类有构造方法,但是是私有的
 
    枚举中的values()方法会返回枚举中的所有枚举值
    枚举中可以定义方法和属性,最后的一个枚举值要以分号和类定义分开,枚举中可以定义的构造方法。
    枚举不能继承类(本身有父类),但可以实现接口,枚举不能有子类也就是final的,枚举的构造方法是private(私有的)。
    枚举中可以定义抽象方法,可以在枚举值的值中实现抽象方法。
    枚举值就是枚举的对象,枚举默认是final,枚举值可以隐含的匿名内部类来实现枚举中定义抽象方法。
 
(2)枚举类(Enumeration Classes)和类一样,具有类所有特性。Season2的父类是java.lang.Enum;
    隐含方法: 每个枚举类型都有的方法。
    Season2[] ss=Season2.values();     ----获得所有的枚举值 
    for(Season2 s:ss){
      System.out.println(s.name());   ----- 打印枚举值
      System.out.println(s.ordinal()); ----- 打印枚举值的编号
    }
 
 
(3)  enum可以switch中使用(不加类名)。
  switch( s ){
 case SPRING:
   …………….
 case SUMMER:
   …………….
 …………..
  }


(4)枚举的有参构造
  enum Season2{
 SPRING(“春”),-------------------------------逗号
 SUMMER(“夏”),-----------------------------逗号
 AUTUMN(“秋”),-----------------------------逗号
 WINTER(“冬”);------------------------------ 分号
 private String name;
 Season2(String name){    //构造方法必须是私有的,可以不写private,默认就是私有的
  this.name=name;
        }
        String getName(){
         return name;
        }

  }
  Season2.SPRING.getName()         ---------------------春
 

(5)枚举中定义的抽象方法,由枚举值实现:
  enum Operation{
 ADD('+'){
  public double calculate(double s1,double s2){
   return s1+s2;
  }
 },
 SUBSTRACT('-'){
  public double calculate(double s1,double s2){
   return s1-s2;
  }
 },
 MULTIPLY('*'){
  public double calculate(double s1,double s2){
   return s1*s2;
  }
 },
 DIVIDE('/'){
  public double calculate(double s1,double s2){
   return s1/s2;
  }
 };
 char name;
 public char getName(){
  return this.name;
 }
 Operation(char name){
  this.name=name;
 }
 public abstract double calculate(double s1 ,double s2);
  }
  有抽象方法枚举元素必须实现该方法。
 
  Operator[] os = Operator.values();
  for(Operator o:os){
     System.out.println("8 "+o.name()+" 2="+o.calculate(8,2));
  }
  for(Operator o:os){
     System.out.println("8 "+o.getName()+" 2="+o.calculate(8,2));
  } 
 
  运行结果:
  8 ADD 2=10.0
  8 SUBSTRACT 2=6.0
  8 MULTIPLY 2=16.0
  8 DIVIDE 2=4.0
  8 + 2=10.0
  8 - 2=6.0
  8 * 2=16.0
  8 / 2=4.0
 
 
2、泛型  (Generic)
(1)增强了java的类型安全,可以在编译期间对容器内的对象进行类型检查,在运行期不必进行类型的转换。
   而在java se5.0之前必须在运行期动态进行容器内对象的检查及转换,泛型是编译时概念,运行时没有泛型

   减少含糊的容器,可以定义什么类型的数据放入容器
  
(2)List<Integer> aList = new ArrayList<Integer>();
   aList.add(new Integer(1));
   // ...
   Integer myInteger = aList.get(0);  //从集合中得到的元素不必强制类型转换
   支持泛型的集合,只能存放制定的类型,或者是指定类型的子类型。  

   HashMap<String,Float> hm = new HashMap<String,Float>();
  
   不能使用原始类型
   GenList<int> nList = new GenList<int>(); //编译错误
  
   编译类型的泛型和运行时类型的泛型一定要一致。没有多态。
   List<Dog> as = new ArrayList<Dog>();
   List<Animal> l = as;  //error  Animal与Dog的父子关系不能推导出List<Animal> 与 List<Dog> 之间的父子类关系
  
(3)泛型的通配符"?"  
   ?   是可以用任意类型替代。
   <?> 泛型通配符表示任意类型
   <? extends 类型>  表示这个类型是某个类型或接口的子类型。
   <? super 类型>    表示这个类型是某个类型的父类型。

  import java.util.*;
  import static java.lang.System.*;
  public class TestTemplate {
 public static void main(String[] args) {
  List<Object> l1=new ArrayList<Object>();
  List<String> l2=new ArrayList<String>();
  List<Number> l3=new ArrayList<Number>();  //Number --- Object的子类,所有封装类的父类
  List<Integer> l4=new ArrayList<Integer>();
  List<Double> l5=new ArrayList<Double>();
  
  print(l1);
  print(l2);
  print(l3);
  print(l4);
  print(l5);
 }
       static void print(List<? extends Number> l){    //所有Number及其子类 l3,l4,l5通过
  for(Number o:l){
   out.println(o);
  }
 }
       static void print(List<? extends Comparable> l){……}    //任何一个实现Comparable接口的类 l2,l4,l5通过
       static void print(List<? super Number> l){……}          //所有Number及其父类 l1,l3通过
      // "?"可以用来代替任何类型, 例如使用通配符来实现print方法。
       public static void print(GenList<?> list){……} //表示任何一种泛型

  }

(4)泛型方法的定义 --- 相当于方法的模版
  把数组拷贝到集合时,数组的类型一定要和集合的泛型相同。
  <...>定义泛型,其中的"..."一般用大写字母来代替,也就是泛型的命名,其实,在运行时会根据实际类型替换掉那个泛型。
  在方法的修饰符和返回值之间定义泛型
  <E> void copyArrayToList(E[] os,List<E> lst){……}
  static <E extends Number & Comparable> void copyArrayToList(E[] os,List<E> lst){……}   //定义泛型的范围 类在前接口在后
  static<E , V extends E> void copyArrayToList(E[] os,List<E> lst){……} //定义多个泛型
  "super"只能用在泛型的通配符上,不能用在泛型的定义上
 
  import java.util.*;
  public class TestGenerics3 {
 public static void main(String[] args) {
  List<String> l1=new ArrayList<String>();
  List<Number> l2=new ArrayList<Number>();
  List<Integer> l3=new ArrayList<Integer>();
  List<Double> l4=new ArrayList<Double>();
  List<Object> l5=new ArrayList<Object>();
  String[] s1=new String[10];
  Number[] s2=new Number[10];
  Integer[] s3=new Integer[10];
  Double[] s4=new Double[10];
  Object[] s5=new Object[10];
  copyFromArray(l1,s1);
  copyFromArray(l2,s2);
  copyFromArray(l3,s3);
  copyFromArray(l4,s4);
  copyFromArray(l5,s5);
  
 }
 //把数组的数据导入到集合中
 public static <T extends Number&Comparable> void copyFromArray(List<T> l,T[] os){
  for(T o:os){
   l.add(o);
  }
 }
  }
 
  受限泛型是指类型参数的取值范围是受到限制的. extends关键字不仅仅可以用来声明类的继承关系, 也可以用来声明类型参数(type parameter)的受限关系.
  泛型定义的时候,只能使用extends不能使用 super,只能向下,不能向上。
  调用时用<?>定义时用 <E>
 
(5)泛型类的定义
  类的静态方法不能使用泛型,因为泛型类是在创建对象的时候产生的。
  class MyClass<E>{
 public void show(E a){
  System.out.println(a);
 }
 public E get(){
  return null;
 }
 
  }

  受限泛型
  class MyClass <E extends Number>{
      public void show(E a){

      }
  } 
 
3、注释(Annotation)
(1)、定义:Annotation描述代码的代码(区:描述代码的文字)
             给机器看         给人看的
(2)、注释的分类:
  1>、标记注释:没有任何属性的注释。@注释名
  2>、单值注释:只有一个属性的注释。@注释名(value=___)
在单值注释中如果只有一个属性且属性名就是value,则“value=”可以省略。
  3>、多值注释:有多个属性的注释。多值注释又叫普通注释。
      @注释名(多个属性附值,中间用逗号隔开)
(3)、内置注释:
  1>、Override(只能用来注释方法)
   表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。
  2>、Deprecated
用 @Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。
  3>、SuppressWarnings(该注释无效)
指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。

(4)、自定义注释
自定义注释
    public  @interface Test{
   
    }
    在自定义注释时,要用注释来注释(描述)注释。
    @target(),用来描述(注释)注释所能够注释的程序员元素。
    @Retention(),描述(注释)注释要保留多久。
    注释的属性类型可以是
    8种基本类型
    String
    Enum
    Annotation
    以及它们的数组

(5)、注释的注释:java.lang. annotation包中======元注释
(1)、Target:指示注释类型所适用的程序元素的种类。
 例:@Target(value = {ElementType.METHOD});
   说明该注释用来修饰方法。
(2)、Retention:指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS。
例:Retention(value = {RetentionPolicy.xxx}
    当x为CLASS表示保留到类文件中,运行时抛弃。
   当x为RUNTIME表示运行时仍保留
   当x为SOURCE时表示编译后丢弃。
(3)、Documented:指示某一类型的注释将通过 javadoc 和类似的默认工具进行文档化。应使用此类型来注释这些类型的声明:其注释会影响由其客户端注释的元素的使用。
(4)、Inherited:指示注释类型被自动继承。如果在注释类型声
明中存在 Inherited 元注释,并且用户在某一类声明中查询该注释类型,同时该类声明中没有此类型的注释,则将在该类的超类中自动查询该注释类型。
  注:在注释中,一个属性既是属性又是方法。
 
 ■ 标注:描述代码的文字
    描述代码的代码。给编译器看的代码,作用是规范编译器的语法。
    class Student{
      @Override
      public String toString(){
        return “student”;
      }
   
    }
  ■ 注释类型 java.lang
    1、标记注释(没有属性)
      @Override
    2、单值注释
      @注释名(a="liucy")
      @注释名(prameter=10)
      int parameter
      特例:
      @注释名 (value=“134” )
      等价于 @注释名 (“134” )
    3.普通注释(多值注释)
    (key1=value,……)
      @__(a="liucy,b=10)

  ■ @Override 只能放在方法前面
    @Deprecated 用于描述过期
    @SuppressWarnings 抑制警告
          @SuperessWarning({“ddd”,”aaa”,”ccc”})  //JVM还没有实现这个注释 
          

4、Java5.0中的并发

 

1>、所在的包:Java.util.concurrent
2>、重写线程的原因:
(1)何一个进程的创建(连接)和销毁(释放资源)的过程都          是一个不可忽视的开销。
(2)run方法的缺陷:没有返回值,没有抛例外。
3>、对比1.4和5.0的线程
       5.0            1.4
ExecutorService       取代 Thread
Callable   Future        取代 Runnable
Lock                           取代 Synchronized
SignalAll                   取代 notifyAll()
await()                       取代 wait()

 

三个新加的多线程包
    

Java 5.0里新加入了三个多线程包:java.util.concurrent, java.util.concurrent.atomic, 
    
  java.util.concurrent.locks. 
  java.util.concurrent包含了常用的多线程工具,是新的多线程工具的主体。

 

这样Java创建线程有 3 种方式:
1. 继承Thread基类。实现run()方法,run()方法就是线程执行流。
    启动:
    a. 创建Thread子类的对象。
    b. 调用该对象的start()方法来启动它。
2. 实现Runnable接口。实现run()方法,run()方法就是线程执行流。
    启动:
    a. 创建Runnable实现类的对象。
    b. 以Runnable实现类的对象作为target参数,创建Thread对象
    c. 调用Thread对象的start()方法来启动它。
前面两种方式的线程执行体(也就是run()方法)不能声明抛出异常,也不能有返回值。
3. 实现Callable接口(它是Runnable的增强版)。
      实现call()(run()的增强版)方法,call()方法就是线程执行流。
    a. 创建Callable实现类的对象。
    b. 将Callable实现类的对象包装FutureTask,它代表了call()方法的返回值将来才会返回。
    c. 以FutureTask的对象作为target参数,创建Thread对象
    d. 调用Thread对象的start()方法来启动它。

实现Runnable接口和实现Callable接口本质相同,
通常我们认为通过实现实现Runnable接口或实现Callable接口的多线程实现方式比较理想。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章