5.0新特性:

5.0新特性:
前提:
1.      JVM没有变, 编译器改变
2.      逐渐和C++融合接近(很多开始被遗弃的C++元素又被捡了回来)
3.      程序员开发越发的简单了
 
5小点:
1 自动封装和自动解封(简单类型和封装类型之间),但只是在必要的时候进行,比如向上就近原则中public static void method(Byte b){}:调用这个方法的时候不会像上就近调用int,而是直接调用这个方法。
Integer i = 3 // OK 封箱
int i = new Integer(3) // OK 解箱
i++ ; // OK ,i是Integer
在方法中的参数也可以自动的封箱解箱,但是如果存在两个方法:
 
方法重载依然存在:
public static void method( Integer I ) { … }
public static void method( int I ) { … }
这个时候调用 method( 10 ) //会调用第二个方法,因为封箱和解箱都是在迫不得已的情况下才会被调用。
 
public static void method( Byte b ) { … }
public static void method( short s ) { … }
这个时候调用 byte b = 1 ; method( byte ) //会调用第二个方法,因为封箱和解箱都是在迫不得已的情况下才会被调用。
 
   同样存在问题:拿byte举例: byte : 256 种(1个字节)然而 Byte : 257 种(多了一个null)  
   所以如果 Integer I = null ; int i = I ; //会有空指针异常
 
   封装类有个重要的特性:就是封装0
       自动解箱要注意的:
Byte b = null;
Byte b = 1;
int i = 0;(默认i=0),有二义性,究竟0是否是有效数字0,还是没有赋值而使用默认给得值; 所以此时用Integer就可以避免这样的二义性。
例如:在hibernate中使用Long而不是long去设定ID的类型,则hibernate会自动检查类型是否是有效数字
 
2        import
System.out中的out是System类得公开静态属性
静态引入:引入一个类里面的静态成员,则访问的时候可以不写类名直接调用静态成员
import static java.lang.System.*;表示引入System中的所有静态属性,则在下面使用的时候out.println(...);   
insert 可以简化更多因为可以加入包是静态的方法直接使用
例:import static java.lang.System.*;
public class Test {
       public static void main(String[] args) {
               out.println("sdsd");
              }
       }
3        新的遍历方法而且非常的方便for/in loop
使用该loop得对象必须实现Interable接口
例:
String ss[] = {“test”,”text”};
For(String s:ss){
        System.out.ptintln(s);
}
 
4        变常参数 public static void m ( String…s) 通过编译器的帮忙可以简化很多,比如反射中就不用再把String.class先封装在Class[] 中了而可以直接的是用。
但是需要注意在一个方法中只能有一个String…s ,其前面可以跟别的类型参数如int i ,String…s
还有就是如果有两个以上的参数String…s必须放在最后参数上。
.先绝对匹配,如果没有匹配的再去调用
.变参和数组不能同时存在,变参即数组
.不能同时存在多个...,一个方法可以有且只能有一个变参,且该变参只能是参数表中的最后一个
       
5        格式化输出:
 System.out.printf(“%d” , 4 ) ;完全符合C的习惯风格,是很有用的东西。格式在API中写的十分的详细。
java.util.Formatter类--〉格式化输出。
java,util,Scanner类--〉格式化输入。融合了BufferedReader+StringTokinizer的功能
 
四大块:
1.        ★枚举(enum) (一种数据类型)java.lang.Enum
对象要用大写来写
其实enum可以用class来实现:
Class Season {
       public static final Season SPRINT = new Season() ; // 这就是制定的对象
       private Season() { } //切记把构造方法写成私有
}
可以很好的控制参数的种类和数量,保证必须按照程序员安排的选择。
提高安全性,避免了无谓的异常抛出。
       同样可以排序:通过CompareTo()方法
       直接通过类名.对象选择所要的对象,而这些对象是程序员写好的,只能是他定义的那几个对象。
       类名[] c = 类名.values() ;可以得到所有的对象。
      
Enum中有个很诡异的事情,咱们可以理解 enum ó final c lass 但是enum中却可以有抽象方法,而这些抽象方法只能通过定义好的几个对象来实现,而且只能通过匿名的内部类的方法来实现。
      
★枚举是一个数据类型,是一个final类,不能有子类
 
类型不安全的枚举类型:
     公开静态常量
 
类型安全的枚举模式:
    将公开静态常量作为public,将构造方法私有,实现枚举类型
 
java 5.0 引入的新类:java.lang.Enum
 
★实现一个枚举类型,调用该类的values()方法,则返回枚举值得数组
final class Season{   //自己实现的枚举类
       public static final Season SPRING = new Season("春");
       public static final Season SUMMER = new Season("夏");
}
 
★用枚举类:
enum Season2{
       SPRING(),   //把参数写在()里面
       SUMMER();   //枚举值和属性之间用;隔开
 
       private String name;
 
       private Season2(String name){   
//此处不能写public,必须是私有的,不写就可以,默认就是private
              this.name = name;
       }
 
       public String getName(){
              return this.name;
       }
}
★.一个枚举值就是一个枚举对象,构造一个枚举值就是调用相应的构造参数
 
★★.final里面不能有枚举类型,枚举本来是final但是隐含的可以用匿名内部类去继承,里面却可以有abstract.
例: enum Operation{
       ADD{
              public abstract double caculator(double d1,double d2){
                     return d1+d2;
              }
       },      
//相当于隐含有一个匿名内部类继承了父类Operation,Operation类已经成为父类,ADD其实是匿名内部类的对象
       SUB,
       MUL,
       PROVIDE;
 
       //抽象方法要求每个枚举值去实现该方法
       public abstract double caculator(double d1,double d2){
             
       }
      
       public static void main(String args[]){
              for(Operation o:)
       }
}
 
2.        泛型:(编译时信息)
★很好的解决了集合中对象很难管理其类型的难题。
List<Object> l = new ArrayList<String>() ; //这是错误的这里不存在多态
List<String> l = new Arraylist<String>() ; // OK
泛型的通配符<?>
List < ? extends Number > 表示可以是Number类和其子类
List < ? super Number > 表示可以使Number类和其父类
public static < E > void m( E[] os , List<E> ls ) 这里的<E>很像C++中的模版
 
★ArrayList比较数组是类型不安全的,指得是里面的类型强转时有可能转换错误
 
public class TestGenerics1{
       public static void main(String args[]){
              List<String> l = new ArrayList<String>();
              l.add("abc");
              //l.add(123);   //此处会报错,泛型要求不能放入非字符串
              l.get(0);     //取得时候也不需要类型转换
 
              for(String s:l){   //用for/in loop打印出list里面的东西
                     System.out.println(s);
              }
             
              List<List> l2 = new ArrayList<List>();
              L2.add(new ArrayList());
              L2.add(new LinkedList());
              L2.add(new Vector());
              L2.add(new HashSet());    //以上都是正确的
 
              Set<Number> s = new HashSet<Number>();
              s.add(1.2);
 
              Map<String,Integer> m = new HashMap<String,Integer>();
              m.put(“A”,65);      //不用强制类型转换了,使用了自动解箱
             
              //List<Object> ll = new ArrayList<String>();
               |不能这样写,因为对象变量的泛型和对象的泛型必须是一致的,不存在多态
               |如果这句话对的话,String泛型就没用了
       }    |
}        |
-------------|--------------------------------------------------------
        \|/例:
import static java.lang.System.*;
 
public class TestGenerics2{
       public static void main(String args[]){
              List<String> l1= new ArrayList<String>();
              l1.add("abc");
 
              List<Number> l2 = new ArrayList<Number>();
              l2.add(23);
 
              List<Integer> l3 = new ArrayList<Integer>();
              l3.add(23);  
 
              List<Object> l4 = new ArrayList<Object>();
              l4.add("123");
              l4.add(456);
 
              print(l1); //如果下面print方法的参数是某一个固定类型的话,或者是Object,这块就不能这样写,出错         
              print(l2);
 
       }
/
       static void print(List<?> l){   // <?>是泛型的通配符,表示什么类型都可以,写Object的话就写死了,上面的调用就会报错
              for(Object o:l){
                     out.println(o);
              }
       }
/
       //如果要l1,l4不可以调用,l2,l3可以调用则可以
       static void print(List<? extends Number> l){}  
       //<? extends Number>带限制范围的泛型通配符,表示?是Number得子类
/
       //如果表示都实现了某个接口,依然用extends
       static void print(List<? extends comparable> l){}  
/
       //如果要l2,l4可以调用,l1,l3不可以调用则可以
       static void print(List<? super Number> l){}
       //<? super Number>表示?是Number得父类
      
}
★泛型方法,在修饰符和返回值之间写泛型
static void copyArrayToList(Object[] os,List<?> ls){
       for(Object o:os){
              ls.add(o);  //报错,因为os放入List,运行的时候List不知道究竟是什么类型
       }
}
 
正确的是:
static <E> void copyArrayToList(E[] os,List<E> ls){
//两个参数:一个E类型的数组,一个存放E对象的List
 
//必须要保证数组的类型和泛型的类型时一样的,每个数组是字符串的,每个元素都是字符串,所以每个字符串当然可以放在泛型是字符串的List中,所以可以使用泛型方法
 
static <E,S extends T> void copyArrayToList(E[] os,List<S> ls){
//两个参数:一个E类型的数组,一个存放E或者E子类的对象的List
       for(E o:os){
              ls.add(o);
       }
}

泛型定义:
<E,T>表示定义了两个泛型,多个泛型定义用,隔开,那么在后面的方法参数表、集合的类型等处应用这两个泛型
 .E是什么类型就看调这个方法的时候怎么传参数的
public static void main(String args[]){
              List<String> l1= new ArrayList<String>();
              l1.add("abc");
              Number[] a1 = new Number[10];
 
              List<Number> l2 = new ArrayList<Number>();
              l2.add(23);
              Number[] a1 = new Number[10];
 
              List<Integer> l3 = new ArrayList<Integer>();
              l3.add(23);  
 
              List<Object> l4 = new ArrayList<Object>();
              l4.add("123");
              l4.add(456);
 
 
              copyArrayToList(a1,l1);
...
}
///
//定义泛型的时候也可以限制范围,只能向下不能向上,即只能是extends,不能用super
 
static <E super Numner> void copyArrayToList(ObjectE[] os,List<E> ls){
       for(E o:os){
              ls.add(o);
       }
}
/
      
       //如果要E是Number而不是Integer,则
       static <E extends Numner&comparator> void copyArrayToList(ObjectE[] os,List<E> ls){
       for(E o:os){
              ls.add(o);
       }
}
<E super Numner&comparator>类名&接口,表示E继承Numner实现comparator
 
--------------------------------------------------------------------------

自定义一个泛型类:
public class TestGenerics1{
       public static void main(String args[]){
              MyClass<String> m = new MyClass<String>();
              MyClass<Integer> m2 = new MyClass<Integer>();
              String s = m.get();  
              Integer i = m2.get();
              //System.out.println(m instanseof MyClass<String>);
              //泛型是编译时概念,到运行的时候什么泛型都没有了,m instanseof MyClass是到运行时才能确定的,所以这句话是不对的
       }
}
class MyClass <E>{
       public void print(E parameter){
             
       }
 
       public E get(){      //返回类型是泛型
              return null;
       }
}
★    ★注意:
* 不能new一个泛型的对象
* 静态方法不能使用类的泛型,
静态变量不能够使用泛型定义
public class MyGenericClass<T> {
 
 public static T value;//错误的定义
 
}
 
此外,泛型的定义不会被继承,举个例子来说,如果A是B的子类,而C是一个声明了泛型定义的类型的话,C<A>不是C<B>的子类。为了更好的说明,可以看下面的代码,这段代码是
错误的。
 
List<String> strList =new ArrayList<String>();
 
List<Object> objList=strList; //错误的赋值
 
 
 
不过这样一段代码是正确的:
 
List<Object> strList =new ArrayList<Object>();
 
strList.add("jsdkfjsdl");
 
 
 
 
 
那么,在什么时候我们应该使用统配类型,什么时候我们应该使用泛型函数呢?答案是取决于函数参数之间,函数参数和返回值之间的类型依赖性。
 
如果一个函数的参数类型与函数返回的参数没有必然关联,同时对于该函数其他的参数的类型也没有依赖关系,那么我们就应该使用统配符,否则就应该使用泛型函数。
 
为了更清楚地说明这一点,我们可以看一下java.util包中Collections类型几个方法的定义:
 
class Collections {
 
        static void swap(List<?> list, int i, int j) {...}
 
        static <T> void copy  (List<? super T> dest, List<? extends T> src)    {...}
 
}
 
其中swap函数实际上也可以这样定义:
 
static <T>void swap(List<T> list, int i, int j) {...}
 
但是注意到这里泛型类型参数T只在参数中用到了一次,也就是说它和函数其他部分没有依赖性,这可以看作是我们应该使用?的一个标志。
 
copy方法中,拷贝源src中的元素必须是dest所能够接受的,src中的元素必须是T的一个子类,但是具体它是哪种子类我们又不必关心,所以方法中使用了泛型作为一个类型参数,
同时也用了统配类型作为第二类型参数


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/chenpy/archive/2007/06/17/1655448.aspx

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值