java 1.5 引入了
- 泛型
- 增強循環,可以使用迭代方式(也稱foreach語句)
- 自動裝箱與自動拆箱
- 枚舉
- 可變參數
- 靜態導入
- 線程并發庫
- 內省
1. 泛型:
C++ 通過模板技術可以指定集合的元素類型,而Java在1.5之前一直沒有相對應的功能。一個集合可以放任何類型的對象,相應地從集合里面拿對象的時候我們也 不得不對他們進行強制得類型轉換。jdk1.5之后引入了泛型,它允許指定集合里元素的類型,這樣你可以得到強類型在編譯時刻進行類型檢查的好處。
//給集合指定存入類型,上面這個集合在存入數據的時候必須存入String類型的數據,否則編譯器會報錯
List<String> strs = new ArrayList<String>();
2.增強for循環(for-each語句)
格式:for(ElementType element:arrayName){};
ElementType可以是數組或者實現了Iterable接口的集合類, 使用增強for循環的時候會忽略角標信息,所以在需要角標的時候最好還是使用傳統的方式。
String [] strs = {'a','b','c'};
for(String s : strs){
System.out.println(s);
}
3.自動拆箱和裝箱功能
什么意思呢?
自動裝箱的過程:每當需要一種類型的對象時,這種基本類型就自動地封裝到與它相同類型的包裝中。
自動拆箱的過程:每當需要一個值時,被裝箱對象中的值就被自動地提取出來,沒必要再去調用intValue()和doubleValue()方法。
自動裝箱,只需將該值賦給一個類型包裝器引用,java會自動創建一個對象。
自動拆箱,只需將該對象值賦給一個基本類型即可。
java為了效率,定義了8中基本數據類型: byte short int long
char float double boolean 但是他們不是對象,沒有指定的方法,所以他們有對應的封裝類,而且內部定義了一些方法(定義泛型的時候用到基本數據類型的時候只能用其封裝類)
java——類的包裝器
類型包裝器有:Double,Float,Long,Integer,Short,Character和Boolean
例如:
基本數據類型 ------------------- 封裝類
byte -------------------- Byte
short -------------------- Short
int -------------------- Integer
long -------------------- Long
char -------------------- Character
float -------------------- Float
double -------------------- Double
boolean -------------------- Boolean
Integer intNum = 13; //自動裝箱
int intNum2 = new Integer(13);//自動拆箱
//必須手動裝箱拆箱
Integer intNum3 = new Integer(13); //手動裝箱
int intNum4 = intNum3.intValue();//手動拆箱
自動裝包:將基本類型轉換成為對象,例如:int --> Integer
自動拆包:將對象轉換成為基本數據類型,例如:Integer --> int
對于JDK1.5之前集合總不能存放基本數據類型的問題,現在也能夠解決。
4.枚舉
把集合里的對象元素一個一個提取出來。枚舉類型使代碼更具可讀性,理解清晰,易于維護。枚舉類型是強類型的,從而保證了系統安全性。而以類的靜態字段實現的類似替代模型,不具有枚舉的簡單性和類型安全性。
簡單的用法:JavaEnum簡單的用法一般用于代表一組常用常量,可用來代表一類相同類型的常量值。
復雜用法:Java為枚舉類型提供了一些內置的方法,同事枚舉常量還可以有自己的方法。可以很方便的遍歷枚舉對象。
枚舉類的定義格式:
enum 類名{
//枚舉值
}
有些方法在運行時,它需要的數據不能是任意的,而必須是一定范圍內的
值,有了枚舉之后可以直接使用枚舉解決。比如: 方向 , 性別 , 季節 ,星期等
枚舉要注意的細節:
1.枚舉類也是一個特殊的類。
2.枚舉值默認的修飾符是public static final。
3.枚舉值就是是枚舉值所屬的類的類型, 然后枚舉值是指向了本類的對象的。
4.枚舉類的構造方法默認的修飾符是private的。
5.枚舉類可以定義自己的成員變量與成員函數。
6.枚舉類可以自定義構造函數,但是構造函數的修飾符必須是private。
7.枚舉類可以存在抽象的方法,但是枚舉值必須要實現抽象的方法。
8.枚舉值必須要位置枚舉類的第一個語句。
9.枚舉值可以用于switch語句
示例:
//定義代表交通燈的枚舉
public enum MyEnum{
RED,GREEN,YELLOW
}
enum Sex{
man("男"){
@Override
public void run() {
System.out.println("男人在跑...");
}
},woman("女"){
@Override
public void run() {
System.out.println("女人在跑...");
}
}; //枚舉值
String value; //成員變量
// public static final Sex man = new Sex();
//構造函數
private Sex(String value){
this.value = value;
}
//成員函數
public void getValue(){
System.out.println("value :"+ value);
}
public abstract void run();
}
public class Demo {
public static void main(String[] args) {
Sex sex = Sex.man; //獲取到了枚舉類的對象
sex.value = "男";
sex.getValue();
sex.run();
//結果 :value :男
男人在跑...
}
}
5.可變參數
什么意思呢?先舉個例子:在JDK1.5以前,當我們要為一個方法傳遞多個類型相同的參數時,我們有兩種方法解決,1.直接傳遞一個數組過去,2.有多少個參數就傳遞多少個參數。
例如:
public void printColor(String red,String green,String yellow){
}
或者
public void printColor(String[] colors){
}
這樣編寫方法參數雖然能夠實現我們想要的效果,但是,這樣是不是有點麻煩呢?再者,如果參數個數不確定,我們怎么辦呢?Java JDK1.5為我們提供的可變參數就能夠完美的解決這個問題。
可變參數其實就是維護了一個數組,此時可以使用可變參數,格式 類型... 變量名
例如:
public void add(int... nums){
int sum = 0;
for (int i : nums){
sum+=i;
}
System.out.println("和是: " + sum);
}
可以這樣定義,什么意思呢?如果參數的類型相同,那么可以使用“類型+三個點,后面跟一個參數名稱”的形式。這樣的好處就是,只要參數類型相同,無論傳遞幾個參數都沒有限制
注意:可變參數必須是參數列表的最后一項(該特性對對象和基本數據類型都適用)
6.靜態導入
優點:使用靜態導入可以使被導入類的所有靜態變量和靜態方法在當前類直接可見,使用這些靜態成員無需再給出他們的類名。(簡化書寫)
缺點:過度使用會降低代碼的可讀性
通過使用 import static,就可以不用指定 Constants 類名而直接使用靜態成員,包括靜態方法。
import xxxx 和 import static xxxx的區別是前者一般導入的是類文件如import java.util.Scanner;后者一般是導入靜態的方法,import static java.lang.System.out
靜態導入的格式:
import static 包名.類名.靜態的成員;
靜態導入要注意:
如果靜態導入的成員與本類的成員存在同名的情況下,那么默認使用本類的靜態成員,如果需要指定使用靜態導入的成員,那么需要在靜態成員前面加上類名。個人感覺靜態導入還是少用比較好,包的機制有個重要的作用就是避免命名的問題。
import static java.lang.System.out;
public class Demo1 {
public static void main(String[] args) {
out.println("haha...");
}
}
7.線程并發庫
線程并發庫是Java1.5提出的關于多線程處理的高級功能,所在包:java.util.concurrent
包括:
①線程互斥
工具類描述:Lock,RedWriteLock
②線程通信
描述:Condition
③線程池
ExecutorService
④同步隊列
ArrayBlockingQueue
⑤同步集合
ConcurrentHashMap,CopyOnWriteArrayList
⑥線程同步工具
Semaphore
Lock代替了Synchrinozed的使用,一個Lock可以設置多個Condition監視器,可以實現靈活的線程間通信。
關于線程并發庫的內容還有很多(很重要),這里就不一一列舉了,感興趣的朋友可以查看一下幫助文檔。
8.內省
是 Java語言對Bean類屬性、事件的一種缺省處理方法。例如類A中有屬性name,那我們可以通過getName,setName來得到其值或者設置新 的值。通過getName/setName來訪問name屬性,這就是默認的規則。Java中提供了一套API用來訪問某個屬性的getter /setter方法,通過這些API可以使你不需要了解這個規則(但你最好還是要搞清楚),這些API存放于包java.beans中。
一 般的做法是通過類Introspector來獲取某個對象的BeanInfo信息,然后通過BeanInfo來獲取屬性的描述器 (PropertyDescriptor),通過這個屬性描述器就可以獲取某個屬性對應的getter/setter方法,然后我們就可以通過反射機制來 調用這些方法。
ReflectPoint pt1 = new ReflectPoint(3,5);
BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
Object retVal = null;
for(PropertyDescriptor pd : pds){
Method methodGetX = pd.getReadMethod();
retVal = methodGetX.invoke(pt1);
}
參考文章:
http://www.jb51.net/article/94693.htm
http://www.lxweimin.com/p/a0e06f171c05
http://blog.csdn.net/lgh1117/article/details/48947391