Open Java Project

          Keep it simple, Stupid, Less is more

          BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
            20 Posts :: 0 Stories :: 12 Comments :: 0 Trackbacks

          1、重要的語言變化

          l         泛型(Generics

          l         增強(qiáng)型循環(huán)(foreach

          l         自動封箱(Autoboxing)和解箱(Unboxing

          l         安全類型的Enums

          l         Varargs

          l         靜態(tài)import

          l         Annotations

           

          2、泛型(Generics

          1)問題

          l         從集合中獲得元素時,必須進(jìn)行類型轉(zhuǎn)換:

          ?         類型轉(zhuǎn)換是麻煩的

          ?         類型轉(zhuǎn)換是不安全的,可能在運(yùn)行時發(fā)生類型轉(zhuǎn)換失敗

          l         為什么不能做的更好:告訴編譯器集合中元素的類型?

          ?         讓編譯器加入類型轉(zhuǎn)換功能

          ?         編譯器會保證類型轉(zhuǎn)換的成功

          2)過濾集合的例子

          // Removes 4-letter words from c; elements must be strings
          static void expurgate(Collection c) {
                 for (Iterator i = c.iterator(); i.hasNext();) {
                        String s = (String) i.next();
                        if (s.length() == 4) {
                          i.remove();
                        }
                 }
          }

          3)使用泛型

          // Removes 4-letter words from c
          static void expurgate(Collection<String> c) {
                 for (Iterator<String> i = c.iterator(); i.hasNext();) {
                        if (i.next().length() == 4) {
                          i.remove();
                        }
                 }
          }

          l         更加清晰和安全

          l         沒有類型轉(zhuǎn)換、額外的括號和臨時變量

          l         提供編譯時的類型檢查

          4)泛型不是模板

          l         沒有膨脹的代碼

          l         沒有可怕的復(fù)雜性

          l         沒有模板元程序

          l         簡單的提供編譯時類型安全性和消除類型轉(zhuǎn)換

           

          3、增強(qiáng)型循環(huán)(foreach

          1)問題

          l         遍歷集合是麻煩的事

          l         Iterator通常只有在獲取元素時才會用到

          l         使用Iterator傾向于錯誤:

          ?         Iterator變量在循環(huán)中出現(xiàn)3次

          ?         使你有兩次出錯的機(jī)會

          ?         通常的拷貝粘貼錯誤

          l         為什么不做的更好,如果能讓編譯器來為你處理Iterator?

          2)通常訪問集合元素的例子

          void cancelAll(Collection c) {
                 for (Iterator i = c.iterator(); i.hasNext();) {
                        TimerTask tt = (TimerTask) i.next();
                        tt.cancel();
                 }
          }

          3)使用增強(qiáng)循環(huán)的例子

          void cancelAll(Collection c) {
                 for (Object o : c) {
                        ((TimerTask) o).cancel();
                 }
          }

          l         更加清晰和安全

          l         Iterator無關(guān)

          l         不可能使用錯誤的Iterator

          4)結(jié)合泛型的例子

          void cancelAll(Collection<TimerTask> c) {
                 for (TimerTask task : c) {
                        task.cancel();
                 }
          }

          l         更加簡潔、清晰和安全

          l         代碼準(zhǔn)確表達(dá)它所要做的

          5)對數(shù)組同樣適合

          //Returns the sum of the elements of a
          int sum(int[] a) {
                 int result = 0;
                 for (int i : a) {
                        result += i;
                 }
                 return result;
          }

          l         消除使用數(shù)組索引的錯誤

          l         具有前面所述的優(yōu)點(diǎn)

          6)靈活的嵌套Iterator

          l         通常的例子

          List suits = ...;
          List ranks = ...;
          List sortedDeck = new ArrayList();
          // Broken - throws NoSuchElementException!
          for (Iterator i = suits.iterator(); i.hasNext();) {
                 for (Iterator j = ranks.iterator(); j.hasNext();) {
                        sortedDeck.add(new Card(i.next(), j.next()));
                 }
          }
          // Fixed - a bit ugly
          for (Iterator i = suits.iterator(); i.hasNext();) {
                 Suit suit = (Suit) i.next();
                 for (Iterator j = ranks.iterator(); j.hasNext();) {
                        sortedDeck.add(new Card(suit, j.next()));
                 }
          }

          l         使用增強(qiáng)循環(huán)簡單而靈活

          for (Suit suit : suits) {
                 for (Rank rank : ranks) {
                        sortedDeck.add(new Card(suit, rank));
                 }
          }

           

          4、自動封箱(Autoboxing)和解箱(Unboxing

          1)問題

          l         不能將int放入集合,必須使用Integer

          l         在獲取時轉(zhuǎn)換回來又是麻煩的事

          l         由編譯器來做這些事不是更好嗎?

          2)使用通常方法創(chuàng)建一個頻率表的例子

          public class Freq {
                 private static final Integer ONE = new Integer(1);
           
                 public static void main(String[] args) {
                        // Maps word (String) to frequency (Integer)
                        Map m = new TreeMap();
                        for (int i = 0; i < args.length; i++) {
                          Integer freq = (Integer) m.get(args[i]);
                          m.put(args[i], (freq == null ? ONE : new Integer(
                                   freq.intValue() + 1)));
                        }
                        System.out.println(m);
                 }
          }

          2)結(jié)合自動封箱、泛型和增強(qiáng)循環(huán)的例子

          public class Freq {
                 public static void main(String[] args) {
                        Map<String, Integer> m = new TreeMap<String, Integer>();
                        for (String word : args) {
                          Integer freq = m.get(word);
                          m.put(word, (freq == null ? 1 : freq + 1));
                        }
                        System.out.println(m);
                 }
          }

           

          5、安全類型的Enums

          1)標(biāo)準(zhǔn)的int Enum模式

          public class Almanac {
                 public static final int SEASON_WINTER = 0;
                 public static final int SEASON_SPRING = 1;
                 public static final int SEASON_SUMMER = 2;
                 public static final int SEASON_FALL = 3;
                  ... // Remainder omitted
          }

          l         缺點(diǎn):

          ?         不是安全類型

          ?         沒有名字空間:必須要有常量前綴

          ?         脆弱性:常量被編譯到客戶程序中

          ?         打印出的值不提供信息

          2)安全類型的Enum模式的例子

          import java.io.Serializable;
          import java.util.Arrays;
          import java.util.Collections;
          import java.util.List;
           
          public final class Season implements Comparable, Serializable {
           
                 private final String name;
           
                 public String toString() {
                        return name;
                 }
           
                 private Season(String name) {
                        this.name = name;
                 }
           
                 public static final Season WINTER = new Season("winter");
                 public static final Season SPRING = new Season("spring");
                 public static final Season SUMMER = new Season("summer");
                 public static final Season FALL = new Season("fall");
           
                 private static int nextOrdinal = 0;
                 private final int ordinal = nextOrdinal++;
           
                 public int compareTo(Object o) {
                        return ordinal - ((Season) o).ordinal;
                 }
           
                 private static final Season[] PRIVATE_VALUES = { WINTER, SPRING, SUMMER,
                          FALL };
           
                 public static final List VALUES = Collections.unmodifiableList(Arrays
                          .asList(PRIVATE_VALUES));
           
                 private Object readResolve() {
                        // Canonicalize
                        return PRIVATE_VALUES[ordinal];
                 }
          }

          l         基本想法:使用導(dǎo)出自定義類型的常量,不提供public構(gòu)造方法

          l         修正上面所有的缺點(diǎn)

          l         其它優(yōu)點(diǎn):

          ?         能夠添加任意的方法、域變量

          ?         能夠?qū)崿F(xiàn)接口

          l         缺點(diǎn):

          ?         代碼冗長

          ?         容易出錯:每個常量出現(xiàn)3次

          ?         不能在switch語句中使用

          l         為什么不能做的更好,由編譯器來處理?

          3)安全類型的Enum結(jié)構(gòu)

          l         編譯器支持安全類型的Enum模式

          l         類似典型的Enum(就象C、C++)

          ?         enum Season { WINTER, SPRING, SUMMER, FALL }

          l         更大強(qiáng)大:

          ?         安全類型的Enum模式的所有優(yōu)點(diǎn)

          ?         能夠在switch語句中使用

          4)結(jié)合泛型和增強(qiáng)循環(huán)的Enum例子

          enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES }
          enum Rank { DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, 
                 EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE }
          List<Card> deck = new ArrayList<Card>();
          for (Suit suit : Suit.values()) {
                 for (Rank rank : Rank.values()) {
                        deck.add(new Card(suit, rank));
                 }
          }
          Collections.shuffle(deck);

          5)有域變量、方法和構(gòu)造方法的Enum例子

          public enum Coin {
                 PENNY(1), NICKEL(5), DIME(10), QUARTER(25);
                 
                 Coin(int value) {
                        this.value = value;
                 }
           
                 private final int value;
           
                 public int value() {
                        return value;
                 }
          }

          l         使用Coin的例子:

          public class CoinTest {
                 public static void main(String[] args) {
                        for (Coin c : Coin.values()) {
                          System.out.println(c + ": \t" + c.value() + "¢ \t" + color(c));
                        }
                 }
           
                 private enum CoinColor {
                        COPPER, NICKEL, SILVER
                 }
           
                 private static CoinColor color(Coin c) {
                        switch (c) {
                        case PENNY:
                          return CoinColor.COPPER;
                        case NICKEL:
                          return CoinColor.NICKEL;
                        case DIME:
                        case QUARTER:
                          return CoinColor.SILVER;
                        default:
                          throw new AssertionError("Unknown coin: " + c);
                        }
                 }
          }

           

          6、Varargs

          1)問題

          l         編寫具有任意數(shù)量參數(shù)的方法,必須使用數(shù)組

          l         創(chuàng)建和初始化數(shù)組是麻煩的事

          l         如果由編譯器來實(shí)現(xiàn)不是更好?

          l         就象printf的基本用法一樣

          2)使用java.text.MessageFormat的例子

          Object[] arguments = {
                 new Integer(7),
                 new Date(),
                 "a disturbance in the Force"
          };
          String result = MessageFormat.format(
                 "At {1,time} on {1,date}, there was {2} on planet "
                 + "{0,number,integer}.", arguments);

          3)使用Varargs的例子

          String result = MessageFormat.format(
                 At {1,time} on {1,date}, there was {2} on planet "
                 + "{0,number,integer}.",
                 7, new Date(), "a disturbance in the Force");

          l         format方法的Varargs聲明如下:

          public static String format(String pattern,
                                 Object... arguments)

          l         參數(shù)類型是Object[]

          l         調(diào)用者不需要使用Varargs語法

           

          7、靜態(tài)import

          1)使用類導(dǎo)出常量的例子

          public class Physics {
                 public static final double AVOGADROS_NUMBER = 6.02214199e23;
                 public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
                 public static final double ELECTRON_MASS = 9.10938188e-31;
          }

          l         客戶程序需要使用限定來訪問常量:

          double molecules = Physics.AVOGADROS_NUMBER * moles;

          2)避免限定的錯誤方法

          // "Constant Interface" antipattern - do not use!
          public interface Physics {
                 public static final double AVOGADROS_NUMBER = 6.02214199e23;
                 public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
                 public static final double ELECTRON_MASS = 9.10938188e-31;
          }
           
          public class Guacamole implements Physics {
                 public static void main(String[] args) {
                 double moles = ...;
                 double molecules = AVOGADROS_NUMBER * moles;
                  ...
          }

          l         存在的問題:

          ?         濫用接口:不是用來定義類型的

          ?         實(shí)現(xiàn)細(xì)節(jié)污染導(dǎo)出API

          ?         使客戶程序混亂

          ?         創(chuàng)建長期的承諾

          ?         如果編譯器讓我們避免限定名字不是更好嗎?

          3)解決:靜態(tài)import

          l         類似包的導(dǎo)入

          l         導(dǎo)入類的靜態(tài)成員

          l         可以單個也可以全部導(dǎo)入

          l         使用靜態(tài)import的例子:

          import static org.iso.Physics.*;
          public class Guacamole {
                 public static void main(String[] args) {
                        double molecules = AVOGADROS_NUMBER * moles;
                        ...
                 }
          }

          4)導(dǎo)入方法的例子(Math類)

          l         替代

          x = Math.cos(Math.PI * theta);

          成:

          x = cos(Math.PI * theta);

          5)和Enum一起工作

          import static gov.treas.Coin.*;
          class MyClass {
                 public static void main(String[] args) {
                        int twoBits = 2 * QUARTER.value();
                        ...
                 }
          }

           

          8、元數(shù)據(jù)(Annotations

          1)問題

          l         許多API需要相當(dāng)數(shù)量的樣板文件,如JAX-RPC Web服務(wù)需要成對的接口和實(shí)現(xiàn)

          l         如果能夠注視代碼,使得工具能夠生成樣板文件不是更好?

          l         許多API需要附加的文件來進(jìn)行維護(hù),如Bean需要BeanInfo類文件

          l         如果能夠注視代碼,使得工具能夠生成這些附加文件不是更好?

          2)JAX-RPC Web服務(wù)的例子

          public interface CoffeeOrderIF extends java.rmi.Remote {
                 public Coffee [] getPriceList()
                        throws java.rmi.RemoteException;
                 public String orderCoffee(String name, int quantity)
                        throws java.rmi.RemoteException;
          }
          public class CoffeeOrderImpl implements CoffeeOrderIF {
                 public Coffee [] getPriceList() {
                        ...
                 }
                 public String orderCoffee(String name, int quantity) {
                        ...
                 }
          }

          3)使用Annotations的例子

          import javax.xml.rpc.*;
          public class CoffeeOrder {
                 @Remote public Coffee [] getPriceList() {
                        ...
                 }
                 @Remote public String orderCoffee(String name, int quantity) {
                        ...
                 }
          }
          posted on 2005-03-21 21:58 nelson_tu 閱讀(1735) 評論(0)  編輯  收藏 所屬分類: Tiger系列
          主站蜘蛛池模板: 广昌县| 平谷区| 阿拉善盟| 栾川县| 东丽区| 婺源县| 喀什市| 莲花县| 勐海县| 鄯善县| 介休市| 贺兰县| 老河口市| 诸城市| 繁昌县| 博野县| 修文县| 大竹县| 喀喇沁旗| 永年县| 瑞金市| 旅游| 呼伦贝尔市| 施甸县| 乌兰浩特市| 平乐县| 青神县| 木里| 玛沁县| 黑山县| 磐安县| 宜宾县| 潮安县| 察雅县| 台中市| 泾阳县| 上饶县| 襄汾县| 邛崃市| 龙州县| 阿鲁科尔沁旗|