黑马程序员_Java1.5新特性

来源:互联网 发布:js获取li标签的属性值 编辑:程序博客网 时间:2024/06/06 18:49

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

可变参数

定义格式:返回值类型  方法名   (参数类型 ... 形式参数)  {  }

特点:

只能出现在参数列表的最后,  符号... 前后有无空格都可以!

(编译器为可变参数隐含创建了一个数组,在函数中以数组的形式访问可变参数)


高级for循环

用于遍历数组或定义泛型的集合.

for(变量类型 变量名 : 集合变量名)

{

代码块;

}

代码书写简单,可是迭代器使用时可以使用删除等功能!

public class Test6 {public static void main(String[] args) {show(1,2,3,5,6,8,9);}public static void show(int ... arr){for(int i : arr){System.out.println(i);}}}


自动装箱:

可把一个基本类型变量直接赋给对应的包装类对象或则Object对象

自动拆箱:

允许把 包装类对象直接赋给对应的基本数据类型


静态导入

书写的时候可以省略类名

import static  java.util.Arrays.*;//导入的是Arrays这个类中的所有静态成员。

import static  java.lang.System.*;//导入了System类中所有静态成员。

泛型

Jdk 1.5以前的集合类中存在什么问题
ArrayList collection = new ArrayList();
collection.add(1);
collection.add(1L);
collection.add("abc");
int i = (Integer) collection.get(1);//编译要强制类型转换且运行时出错!
Jdk 1.5的集合类希望你在定义集合时,明确表示你要向集合中装哪种类型的数据,无法加入指定类型以外的数据
ArrayList<Integer> collection2 = new ArrayList<Integer>();
collection2.add(1);
/*collection2.add(1L);
collection2.add(“abc”);*///这两行代码编译时就报告了语法错误
int i2 = collection2.get(0);//不需要再进行类型转换


泛型是提供给javac编译器使用的,
利用反射穿透泛型限制 (暴力反射)
泛型能绝对保证集合中存入数据都是它限定的类型吗?先看下边的代码 

import java.util.ArrayList;public class Demo23 {public static void main(String[] args) {ArrayList<Integer> collection2 = new ArrayList<Integer>();   System.out.println(collection1.getClass()==collection2.getClass());   collection2.add(“真暴力”);//这句会报错    collection2.getClass().getMethod("add", Object.class).invoke(collection2, "真暴力");   System.out.println(collection2.get(0)); //结果却为真暴力  //已经限制集合中元素的类型为Integer,可用反射却能将String存入,为什么? 这是因为泛型是给编译器               用的,运行时就没有这些泛型信息了,这叫做“去泛型化”,所以可以通过反射,获取集合字节码加入非指定的类型。}}



泛型中的?通配符的扩展

  限定通配符的上边界:
正确:Vector<? extends Number> x = new Vector<Integer>();
错误:Vector<? extends Number> x = new Vector<String>();
  限定通配符的下边界:
正确:Vector<? super Integer> x = new Vector<Number>();
错误:Vector<? super Integer> x = new Vector<Byte>();
提示:
限定通配符总是包括自己。
?只能用作引用,不能用它去给其他变量赋值
Vector<? extends Number> y = new Vector<Integer>();
Vector<Number> x = y;
上面的代码错误,原理与Vector<Object > x11 = new Vector<String>();相似,
只能通过强制类型转换方式来赋值。



泛型集合类的综合案例  
能写出下面的代码即代表掌握了Java的泛型集合类:  

 HashMap<String,Integer> hm = new HashMap<String,Integer>();    hm.put("zxx",19);    hm.put("lis",18);        Set<Map.Entry<String,Integer>> mes= hm.entrySet();    for(Map.Entry<String,Integer> me : mes) {     System.out.println(me.getKey() + ":" + me.getValue());    }  

由C++的模板函数引入自定义泛型  
如下函数的结构很相似,仅类型不同:  
int add(int x,int y) {  
            return x+y;  
     }    
float add(float x,float y) {  
            return x+y;       
    }     
double add(double x,double y) {  
            return x+y;       
    }     
C++用模板函数解决,只写一个通用的方法,它可以适应各种类型,示意代码如下:  
    template<class T>   
    T add(T x,T y) {  
            return (T) (x+y);  
    }  

类型参数的类型推断
编译器判断范型方法的实际类型参数的过程称为类型推断,类型推断是相对于知觉推断的,其实现方法是一种非常复杂的过程。
根据调用泛型方法时实际传递的参数类型或返回值的类型来推断,具体规则如下:
1.当某个类型变量只在整个参数列表中的所有参数和返回值中的一处被应用了,那么根据调用方法时该处的实际应用类型来

确定,这很容易凭着感觉推断出来,即直接根据调用方法时传递的参数类型或返回值来决定泛型参数的类型,例如:
 swap(new String[3],3,4)   à    static <E> void swap(E[] a, int i, int j)
2.当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型都对应
同一种类型来确定,这很容易凭着感觉推断出来,例如:
 add(3,5)   à static <T> T add(T a, T b) 
3.当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型对应到
了不同的类型,且没有使用返回值,这时候取多个参数中的最大交集类型,例如,下面语句实际对应的类型就是Number了,编
译没问题,只是运行时出问题:fill(new Integer[3],3.5f)   à static <T> void fill(T[] a, T v) 
4.当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型对应到
了不同的类型, 并且使用返回值,这时候优先考虑返回值的类型,例如,下面语句实际对应的类型就是Integer了,编译将报


告错误,将变量x的类型改为float,对比eclipse报告的错误提示,接着再将变量x类型改为Number,则没有了错误:
 int x =(3,3.5f)   à static <T> T add(T a, T b) 
5.参数类型的类型推断具有传递性,下面第一种情况推断实际参数类型为Object,编译没有问题,而第二种情况则根据参数
化的Vector类实例将类型变量直接确定为String类型,编译将出现问题:
copy(new Integer[5],new String[5]) à static <T> void copy(T[] a,T[]  b);
copy(new Vector<String>(), new Integer[5]) à static <T> void copy(Collection<T> a , T[] b);


定义泛型类型

如果类的实例对象中的多处都要用到同一个泛型参数,即这些地方引用的泛型类型要保持同一个实际类型时,这时候
就要采用泛型类型的方式进行定义,也就是类级别的泛型,语法格式如下:
public class GenericDao<T> {private T field1;public void save(T obj){}public T getById(int id){}}
类级别的泛型是根据引用该类名时指定的类型信息来参数化类型变量的,例如,如下两种方式都可以:
GenericDao<String> dao = null;
new genericDao<String>();
注意:
在对泛型类型进行参数化时,类型参数的实例必须是引用类型,不能是基本类型。
当一个变量被声明为泛型时,只能被实例变量、方法和内部类调用,而不能被静态变量和静态方法调用。因为静态成员是被所
有参数化的类所共享的,所以静态成员不应该有类级别的类型参数。
问题:类中只有一个方法需要使用泛型,是使用类级别的泛型,还是使用方法级别的泛型?
(Create)、查询(Retrieve)(重新得到数据)、更新(Update)和删除(Delete)几个单词的首字母简写  

import java.util.Set;    //dao data access object(数据访问对象)--->crud  public class GenericDao<E>  {      public void add(E x){      }      public E findById(int id){          return null;      }      public void delete(E obj){      }      public void delete(int id){      }         public void update(E obj){      }      public static <E> void update2(E obj){      }      public E findByUserName(String name){          return null;      }      public Set<E> findByConditions(String where){          return null;      }  } 

枚举


枚举类的对象只能为若干固定对象中的一个否则就会报错.
以前没有枚举类的时候
1,私有构造函数
2,公有静态成员变量

枚举就是一个特殊的类,所有枚举类都是java.lang.Enum的子类,所以枚举类不能再继承其他类.但可以实现多个接口.
枚举类可以有构造函数,但必须是private的

枚举内部抽象方法,所有枚举对象都必须实现

public enum Lamp {RED {public Lamp nextLamp() {return GREEN;}},GREEN {public Lamp nextLamp() {return YELLOW;}},YELLOW {public Lamp nextLamp() {return RED;}};public abstract Lamp nextLamp();}


构造方法
public enum LampDemo2 {RED("GREEN"),GREEN("YELLOW"),YELLOW("RED");private String nextLamp;private LampDemo2(String nextLamp) {this.nextLamp = nextLamp;}String nextLamp(){return nextLamp;}}class Test{public static void main(String[] args) {System.out.println(LampDemo2.RED.nextLamp());}}


switch(枚举)

public enum LampDemo1 {RED,GREEN,YELLOW;public LampDemo1 nextLamp(){switch(this){case RED:return GREEN;case GREEN:return YELLOW;case YELLOW:return RED;}return null;}}



----------- android培训java培训、java学习型技术博客、期待与您交流! ------------


0 0
原创粉丝点击