1 泛型(Generic)
1.1 說(shuō)明
增強(qiáng)了java的類型
安全,可以在編譯期間對(duì)容器內(nèi)的對(duì)象進(jìn)行類型檢查,在運(yùn)行期不必進(jìn)行類型的轉(zhuǎn)換。而在j2se5之前必須在運(yùn)行期動(dòng)態(tài)進(jìn)行容器內(nèi)對(duì)象的檢查及轉(zhuǎn)換
減少含糊的容器,可以定義什么類型的數(shù)據(jù)放入容器
代碼內(nèi)容 ArrayList<Integer> listOfIntegers; // <TYPE_NAME> is new to the syntax Integer integerObject; listOfIntegers = new ArrayList<Integer>(); // <TYPE_NAME> is new to the syntax listOfIntegers.add(new Integer(10)); // 只能是Integer類型 integerObject = listOfIntegers.get(0); // 取出對(duì)象不需要轉(zhuǎn)換 |
1.2 用法
聲明及實(shí)例化泛型類:
代碼內(nèi)容 HashMap<String,Float> hm = new HashMap<String,Float>(); //不能使用原始類型 GenList<int> nList = new GenList<int>(); //編譯錯(cuò)誤 J2SE 5.0目前不支持原始類型作為類型參數(shù)(type parameter) |
定義泛型接口:
代碼內(nèi)容 public interface GenInterface<T> { void func(T t); } |
定義泛型類:
public class ArrayList<ItemType> { ... }
public class GenMap<T, V> { ... }
例1:
代碼內(nèi)容 public class MyList<Element> extends LinkedList<Element> { public void swap(int i, int j) { Element temp = this.get(i); this.set(i, this.get(j)); this.set(j, temp); } public static void main(String[] args) { MyList<String> list = new MyList<String>(); list.add("hi"); list.add("andy"); System.out.println(list.get(0) + " " + list.get(1)); list.swap(0,1); System.out.println(list.get(0) + " " + list.get(1)); } } |
例2:
代碼內(nèi)容 public class GenList <T>{ private T[] elements; private int size = 0; private int length = 0;
public GenList(int size) { elements = (T[])new Object[size]; this.size = size; }
public T get(int i) { if (i < length) { return elements[i]; } return null; } public void add(T e) { if (length < size - 1) elements[length++] = e; } } |
泛型方法:
代碼內(nèi)容 public class TestGenerics{ public <T> String getString(T obj) { //實(shí)現(xiàn)了一個(gè)泛型方法 return obj.toString(); } public static void main(String [] args){ TestGenerics t = new TestGenerics(); String s = "Hello"; Integer i = 100; System.out.println(t.getString(s)); System.out.println(t.getString(i)); } } |
1.3 受限泛型
受限泛型是指類型參數(shù)的取值范圍是受到限制的. extends關(guān)鍵字不僅僅可以用來(lái)聲明類的繼承關(guān)系, 也可以用來(lái)聲明類型參數(shù)(type parameter)的受限關(guān)系.例如, 我們只需要一個(gè)存放數(shù)字的列表, 包括整數(shù)(Long, Integer, Short), 實(shí)數(shù)(Double, Float), 不能用來(lái)存放其他類型, 例如字符串(String), 也就是說(shuō), 要把類型參數(shù)T的取值泛型限制在Number極其子類中.在這種情況下, 我們就可以使用extends關(guān)鍵字把類型參數(shù)(type parameter)限制為數(shù)字
示例
代碼內(nèi)容 public class Limited<T extends Number> { public static void main(String[] args) { Limited<Integer> number; //正確 Limited<String> str; //編譯錯(cuò)誤 } } |
1.4 泛型與異常
類型參數(shù)在catch塊中不允許出現(xiàn),但是能用在方法的throws之后。例:
代碼內(nèi)容 import java.io.*; interface Executor<E extends Exception> { void execute() throws E; }
public class GenericExceptionTest { public static void main(String args[]) { try { Executor<IOException> e = new Executor<IOException>() { public void execute() throws IOException{ // code here that may throw an // IOException or a subtype of // IOException } }; e.execute(); } catch(IOException ioe) { System.out.println("IOException: " + ioe); ioe.printStackTrace(); } } } |
1.5 泛型的通配符"?"
"?"可以用來(lái)代替任何類型, 例如使用通配符來(lái)實(shí)現(xiàn)print方法。
代碼內(nèi)容 public static void print(GenList<?> list) {}) |
1.6 泛型的一些局限型
不能實(shí)例化泛型
代碼內(nèi)容 T t = new T(); //error |
不能實(shí)例化泛型類型的數(shù)組
代碼內(nèi)容 T[] ts= new T[10]; //編譯錯(cuò)誤 |
不能實(shí)例化泛型參數(shù)數(shù)
代碼內(nèi)容 Pair<String>[] table = new Pair<String>(10); // ERROR |
類的靜態(tài)變量不能聲明為類型參數(shù)類型
代碼內(nèi)容 public class GenClass<T> { private static T t; //編譯錯(cuò)誤 } |
泛型類不能繼承自Throwable以及其子類
代碼內(nèi)容 public GenExpection<T> extends Exception{} //編譯錯(cuò)誤 |
不能用于基礎(chǔ)類型int等
代碼內(nèi)容 Pair<double> //error Pair<Double> //right |
2 增強(qiáng)循環(huán)(Enhanced for Loop)
舊的循環(huán)
代碼內(nèi)容 LinkedList list = new LinkedList(); list.add("Hi"); list.add("everyone!"); list.add("Was"); list.add("the"); list.add("pizza"); list.add("good?"); for (int i = 0; i < list.size(); i++) System.out.println((String) list.get(i)); //或者用以下循環(huán) //for(Iterator iter = list.iterator(); iter.hasNext(); ) { //Integer stringObject = (String)iter.next(); // ... more statements to use stringObject... //} 新的循環(huán) LinkedList<String> list = new LinkedList<String>(); list.add("Hi"); list.add("everyone!"); list.add("Was"); list.add("the"); list.add("pizza"); list.add("good?"); for (String s : list) System.out.println(s); |
很清晰、方便,一看便知其用法
3 可變參數(shù)(Variable Arguments)
實(shí)現(xiàn)了更靈活的方法參數(shù)傳入方式,System.out.printf是個(gè)很好的例子
用法:void test(Object … args)
一個(gè)很容易理解的例子
代碼內(nèi)容 public static int add(int ... args){ int total = 0; for (int i = 0; i < args.length; i++) total += args[i]; return total; } public static void main(String[] args){ int a; a = Varargs.add(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); System.out.println(a); } |
4 自動(dòng)實(shí)現(xiàn)裝箱和解箱操作(Boxing/Unboxing Conversions)
說(shuō)明:實(shí)現(xiàn)了基本類型與外覆類之間的隱式轉(zhuǎn)換。基本類型至外覆類的轉(zhuǎn)換稱為裝箱,外覆類至基本類型的轉(zhuǎn)換為解箱。這些類包括
代碼內(nèi)容 Primitive Type Reference Type boolean Boolean byte Byte char Character short Short int Integer long Long float Float double Double 例如,舊的實(shí)現(xiàn)方式 Integer intObject; int intPrimitive; ArrayList arrayList = new ArrayList(); intPrimitive = 11; intObject = new Integer(intPrimitive); arrayList.put(intObject); // 不能放入int類型,只能使Integer 新的實(shí)現(xiàn)方式 int intPrimitive; ArrayList arrayList = new ArrayList(); intPrimitive = 11; //在這里intPrimitive被自動(dòng)的轉(zhuǎn)換為Integer類型 arrayList.put(intPrimitive); |
5 靜態(tài)導(dǎo)入(Static Imports)
很簡(jiǎn)單的東西,看一個(gè)例子:
沒(méi)有靜態(tài)導(dǎo)入
代碼內(nèi)容 Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); |
有了靜態(tài)導(dǎo)入
代碼內(nèi)容 import static java.lang.Math.*; sqrt(pow(x, 2) + pow(y, 2)); |
其中import static java.lang.Math.*;就是靜態(tài)導(dǎo)入的語(yǔ)法,它的意思是導(dǎo)入Math類中的所有static方法和屬性。這樣我們?cè)谑褂眠@些方法和屬性時(shí)就不必寫類名。
需要注意的是默認(rèn)包無(wú)法用靜態(tài)導(dǎo)入,另外如果導(dǎo)入的類中有重復(fù)的方法和屬性則需要寫出類名,否則編譯時(shí)無(wú)法通過(guò)。
6 枚舉類(Enumeration Classes)
用法:public enum Name {types, ….}
簡(jiǎn)單的例子:
代碼內(nèi)容 public enum Colors {Red, Yellow, Blue, Orange, Green, Purple, Brown, Black} public static void main(String[] args){ Colors myColor = Colors.Red; System.out.println(myColor); } |
又一個(gè)簡(jiǎn)單例子:
代碼內(nèi)容 import java.util.*; enum OperatingSystems {windows, unix, linux, macintosh} public class EnumExample1 { public static void main(String args[]) { OperatingSystems os; os = OperatingSystems.windows; switch(os) { case windows: System.out.println(“You chose Windows!”); break; case unix: System.out.println(“You chose Unix!”); break; case linux: System.out.println(“You chose Linux!”); break; case macintosh: System.out.println(“You chose Macintosh!”); break; default: System.out.println(“I don’t know your OS.”); break; } } } |
應(yīng)運(yùn)enum簡(jiǎn)寫的例子:
代碼內(nèi)容 import java.util.*; public class EnumTest { public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.print("Enter a size: (SMALL, MEDIUM, LARGE, EXTRA_LARGE) "); String input = in.next().toUpperCase(); Size size = Enum.valueOf(Size.class, input); System.out.println("size=" + size); System.out.println("abbreviation=" + size.getAbbreviation()); if (size == Size.EXTRA_LARGE) System.out.println("Good job--you paid attention to the _."); } }
enum Size { SMALL("S"), MEDIUM("M"), LARGE("L"), EXTRA_LARGE("XL");
private Size(String abbreviation) { this.abbreviation = abbreviation; } public String getAbbreviation() { return abbreviation; }
private String abbreviation; } enum類中擁有方法的一個(gè)例子: enum ProgramFlags { showErrors(0x01), includeFileOutput(0x02), useAlternateProcessor(0x04); private int bit; ProgramFlags(int bitNumber) { bit = bitNumber; } public int getBitNumber() { return(bit); } } public class EnumBitmapExample { public static void main(String args[]) { ProgramFlags flag = ProgramFlags.showErrors; System.out.println(“Flag selected is: “ + flag.ordinal() + “ which is “ + flag.name()); } } |
7 元數(shù)據(jù)(Meta data)
請(qǐng)參考
8 Building Strings(StringBuilder類)
在JDK5.0中引入了StringBuilder類,該類的方法不是同步(synchronized)的,這使得它比StringBuffer更加輕量級(jí)和有效。
9 控制臺(tái)輸入(Console Input)
在JDK5.0之前我們只能通過(guò)JOptionPane.showInputDialog進(jìn)行輸入,但在5.0中我們可以通過(guò)類Scanner在控制臺(tái)進(jìn)行輸入操作
例如在1.4中的輸入
代碼內(nèi)容 String input = JOptionPane.showInputDialog(prompt); int n = Integer.parseInt(input); double x = Double.parseDouble(input); s = input; 在5.0中我們可以 Scanner in = new Scanner(System.in); System.out.print(prompt); int n = in.nextInt(); double x = in.nextDouble(); String s = in.nextLine(); |
10 Covariant Return Types(不曉得怎么翻譯)
JDK5之前我們覆蓋一個(gè)方法時(shí)我們無(wú)法改變被方法的返回類型,但在JDK5中我們可以改變它
例如1.4中我們只能
代碼內(nèi)容 public Object clone() { ... } ... Employee cloned = (Employee) e.clone(); |
但是在5.0中我們可以改變返回類型為Employee
代碼內(nèi)容 public Employee clone() { ... } ...
Employee cloned = e.clone(); |
11 格式化I/O(Formatted I/O)
增加了類似C的格式化輸入輸出,簡(jiǎn)單的例子:
代碼內(nèi)容 public class TestFormat{ public static void main(String[] args){ int a = 150000, b = 10; float c = 5.0101f, d = 3.14f; System.out.printf("%4d %4d%n", a, b); System.out.printf("%x %x%n", a, b); System.out.printf("%3.2f %1.1f%n", c, d); System.out.printf("%1.3e %1.3e%n", c, d*100); } } |
輸出結(jié)果為:
150000 10
249f0 a
5.01 3.1
5.010e+00 3.140e+02
下面是一些格式化參數(shù)說(shuō)明(摘自Core Java 2 Volume I - Fundamentals, Seventh Edition)
Table 3-5. Conversions for printf
Conversion Character |
Type |
Example |
d |
Decimal integer |
159 |
x |
|
9f |
o |
Octal integer |
237 |
f |
Fixed-point floating-point |
15.9 |
e |
Exponential floating-point |
1.59E+01 |
g |
General floating-point (the shorter of e and f) |
|
a |
Hexadecimal floating point |
0x1.fccdp3 |
s |
String |
Hello |
c |
Character |
H |
b |
Boolean |
TRUE |
h |
Hash code |
42628b2 |
tx |
Date and time |
|
% |
The percent symbol |
% |
n |
The platform-dependent line separator |
|
Table 3-7. Date and Time Conversion Characters
Conversion Character |
Type |
Example |
C |
Complete date and time |
Mon Feb 09 18:05:19 PST 2004 |
F |
ISO 8601 date |
2004-02-09 |
D |
U.S. formatted date (month/day/year) |
02/09/2004 |
T |
24-hour time |
18:05:19 |
r |
12-hour time |
06:05:19 pm |
R |
|
18:05 |
Y |
Four-digit year (with leading zeroes) |
2004 |
y |
Last two digits of the year (with leading zeroes) |
04 |
C |
First two digits of the year (with leading zeroes) |
20 |
B |
Full month name |
February |
b or h |
|
Feb |
m |
Two-digit month (with leading zeroes) |
02 |
d |
|
09 |
e |
Two-digit day (without leading zeroes) |
9 |
A |
Full weekday name |
Monday |
a |
Abbreviated weekday name |
Mon |
j |
Three-digit day of year (with leading zeroes), between 001 and 366 |
069 |
H |
Two-digit hour (with leading zeroes), between 00 and 23 |
18 |
k |
Two-digit hour (without leading zeroes), between 0 and 23 |
18 |
I |
Two-digit hour (with leading zeroes), between 01 and 12 |
06 |
l |
Two-digit hour (without leading zeroes), between 1 and 12 |
6 |
M |
Two-digit minutes (with leading zeroes) |
05 |
S |
Two-digit seconds (with leading zeroes) |
19 |
L |
Three-digit milliseconds (with leading zeroes) |
047 |
N |
Nine-digit nanoseconds (with leading zeroes) |
047000000 |
P |
Uppercase morning or afternoon marker |
PM |
p |
Lowercase morning or afternoon marker |
pm |
z |
RFC 822 numeric offset from GMT |
-0800 |
Z |
Time zone |
PST |
s |
Seconds since 1970-01-01 00:00:00 GMT |
1078884319 |
E |
|
1078884319047 |
Table 3-6. Flags for printf
Flag |
Purpose |
Example |
+ |
Prints sign for positive and negative numbers |
+3333.33 |
space |
Adds a space before positive numbers |
| 3333.33| |
0 |
Adds leading zeroes |
003333.33 |
- |
Left-justifies field |
|3333.33 | |
( |
Encloses negative number in parentheses |
(3333.33) |
, |
Adds group separators |
3,333.33 |
# (for f format) |
Always includes a decimal point |
3,333. |
# (for x or o format) |
Adds 0x or 0 prefix |
0xcafe |
^ |
Converts to upper case |
0XCAFE |
$ |
Specifies the index of the argument to be formatted; for example, %1$d %1$x prints the first argument in decimal and hexadecimal |
159 9F |
< |
Formats the same value as the previous specification; for example, %d %<x prints the same number in decimal and hexadecimal |
|
這里是一些簡(jiǎn)單的介紹,更詳細(xì)的說(shuō)明請(qǐng)參考:
Core Java 2 Volume I - Fundamentals, Seventh Edition
Core Java 2 Volume II - Advanced Features, Seventh Edition
里面都有一些很精彩的描述,中文名稱就是《Java核心技術(shù)》。只有第七版才有J2SE5.0的介紹
posted on 2005-11-08 16:39
Sung 閱讀(300)
評(píng)論(0) 編輯 收藏 所屬分類:
Java