分享
 
 
 

Tiger系列二:Tiger语言新特性

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

1、重要的语言变化

l 泛型(Generics)

l 增强型循环(foreach)

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

l 安全类型的Enums

l Varargs

l 静态import

l Annotations

2、泛型(Generics)

(1)问题

l 从集合中获得元素时,必须进行类型转换:

Ø 类型转换是麻烦的

Ø 类型转换是不安全的,可能在运行时发生类型转换失败

l 为什么不能做的更好:告诉编译器集合中元素的类型?

Ø 让编译器加入类型转换功能

Ø 编译器会保证类型转换的成功

(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 没有类型转换、额外的括号和临时变量

l 提供编译时的类型检查

(4)泛型不是模板

l 没有膨胀的代码

l 没有可怕的复杂性

l 没有模板元程序

l 简单的提供编译时类型安全性和消除类型转换

3、增强型循环(foreach)

(1)问题

l 遍历集合是麻烦的事

l Iterator通常只有在获取元素时才会用到

l 使用Iterator倾向于错误:

Ø Iterator变量在循环中出现3次

Ø 使你有两次出错的机会

Ø 通常的拷贝粘贴错误

l 为什么不做的更好,如果能让编译器来为你处理Iterator?

(2)通常访问集合元素的例子

void cancelAll(Collection c) {

for (Iterator i = c.iterator(); i.hasNext();) {

TimerTask tt = (TimerTask) i.next();

tt.cancel();

}

}

(3)使用增强循环的例子

void cancelAll(Collection c) {

for (Object o : c) {

((TimerTask) o).cancel();

}

}

l 更加清晰和安全

l 和Iterator无关

l 不可能使用错误的Iterator

(4)结合泛型的例子

void cancelAll(Collection<TimerTask> c) {

for (TimerTask task : c) {

task.cancel();

}

}

l 更加简洁、清晰和安全

l 代码准确表达它所要做的

(5)对数组同样适合

//Returns the sum of the elements of a

int sum(int[] a) {

int result = 0;

for (int i : a) {

result += i;

}

return result;

}

l 消除使用数组索引的错误

l 具有前面所述的优点

(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 使用增强循环简单而灵活

for (Suit suit : suits) {

for (Rank rank : ranks) {

sortedDeck.add(new Card(suit, rank));

}

}

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

(1)问题

l 不能将int放入集合,必须使用Integer

l 在获取时转换回来又是麻烦的事

l 由编译器来做这些事不是更好吗?

(2)使用通常方法创建一个频率表的例子

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)结合自动封箱、泛型和增强循环的例子

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)标准的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 缺点:

Ø 不是安全类型

Ø 没有名字空间:必须要有常量前缀

Ø 脆弱性:常量被编译到客户程序中

Ø 打印出的值不提供信息

(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 基本想法:使用导出自定义类型的常量,不提供public构造方法

l 修正上面所有的缺点

l 其它优点:

Ø 能够添加任意的方法、域变量

Ø 能够实现接口

l 缺点:

Ø 代码冗长

Ø 容易出错:每个常量出现3次

Ø 不能在switch语句中使用

l 为什么不能做的更好,由编译器来处理?

(3)安全类型的Enum结构

l 编译器支持安全类型的Enum模式

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

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

l 更大强大:

Ø 安全类型的Enum模式的所有优点

Ø 能够在switch语句中使用

(4)结合泛型和增强循环的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)有域变量、方法和构造方法的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 编写具有任意数量参数的方法,必须使用数组

l 创建和初始化数组是麻烦的事

l 如果由编译器来实现不是更好?

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 参数类型是Object[]

l 调用者不需要使用Varargs语法

7、静态import

(1)使用类导出常量的例子

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 存在的问题:

Ø 滥用接口:不是用来定义类型的

Ø 实现细节污染导出API

Ø 使客户程序混乱

Ø 创建长期的承诺

Ø 如果编译器让我们避免限定名字不是更好吗?

(3)解决:静态import

l 类似包的导入

l 导入类的静态成员

l 可以单个也可以全部导入

l 使用静态import的例子:

import static org.iso.Physics.*;

public class Guacamole {

public static void main(String[] args) {

double molecules = AVOGADROS_NUMBER * moles;

...

}

}

(4)导入方法的例子(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、元数据(Annotations)

(1)问题

l 许多API需要相当数量的样板文件,如JAX-RPC Web服务需要成对的接口和实现

l 如果能够注视代码,使得工具能够生成样板文件不是更好?

l 许多API需要附加的文件来进行维护,如Bean需要BeanInfo类文件

l 如果能够注视代码,使得工具能够生成这些附加文件不是更好?

(2)JAX-RPC Web服务的例子

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) {

...

}

}

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有