副标题: Effective Java Second Edition
作者: Joshua Bloch
译者: 俞黎敏
出版社: 机械工业出版社
出版年: 2009-1
页数: 287
定价: 52.00元
装帧: 平装
ISBN: 9787111255833
作者: Joshua Bloch
译者: 俞黎敏
出版社: 机械工业出版社
出版年: 2009-1
页数: 287
定价: 52.00元
装帧: 平装
ISBN: 9787111255833
内容简介 · · · · · ·
本书介绍了在Java编程中78条极具实用价值的经验规则,这些经验规则涵盖了大多数开发人员每天所面临的问题的解决方案。通过对Java平台设计专家所使用的技术的全面描述,揭示了应该做什么,不应该做什么才能产生清晰、健壮和高效的代码。
本书中的每条规则都以简短、独立的小文章形式出现,并通过例子代码加以进一步说明。本书内容全面,结构清晰,讲解详细。可作为技术人员的参考用书。
本书中的每条规则都以简短、独立的小文章形式出现,并通过例子代码加以进一步说明。本书内容全面,结构清晰,讲解详细。可作为技术人员的参考用书。
作者简介 · · · · · ·
Joshua Bloch是Sun公司的高级工程师,也是“Java平台核心组”的设计师。他设计并实现了获奖的Java Collections Framework和java.math软件包,并且对Java平台的其他部分也做出了贡献。Joshua是许多技术文章和论文的作者,他的关于抽象数据对象复制的博士论文获得过“ACM杰出博士论文奖”提名。他拥有哥伦比亚大学的学士学位和卡耐基-梅隆大学的博士学位。
豆瓣成员常用的标签(共55个) · · · · · ·
喜欢读"Effective Java中文版"的人也喜欢 · · · · · ·
按有用程度 按页码先后 最新笔记
-
第1页
Wuqifu (喜欢买书的软件工程师~)
本想给这本书4星的,因为感觉没有Scott Meyers的《Effective C++》、《More Effective C++》、《Effective STL》系列写得好;考虑到Java学习上只此一本《Effective Java》还是给5星吧。毕竟这本书也还是很值得一读的! 抄录一些笔记,空白的条目表示没看明白,以后有新的理解再补充。 第一章 引言 一, 代码应该被重用,而不是被拷贝。 第二章 创建和销毁对象 一,考虑用静态工厂方法代替构造器 public static Boolean v... (更多)本想给这本书4星的,因为感觉没有Scott Meyers的《Effective C++》、《More Effective C++》、《Effective STL》系列写得好;考虑到Java学习上只此一本《Effective Java》还是给5星吧。毕竟这本书也还是很值得一读的!抄录一些笔记,空白的条目表示没看明白,以后有新的理解再补充。第一章 引言一, 代码应该被重用,而不是被拷贝。第二章 创建和销毁对象一,考虑用静态工厂方法代替构造器public static Boolean valueOf(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE;} 静态工厂方法能够为重复的调用返回相同的对象。静态工厂惯用名称:valueOf, of, getInstance, newInstance, getType, newType.二, 遇到多个构造器参数时要考虑用builder三,用私有构造器或者枚举类型强化Singleton属性1,public class Elvis { public static final Elvis INSTANCE = new Elvis(); private Elvis() { .... } public void leaveTheBuilding() {...}}2, public class Elvis { private static final Elvis INSTANCE = new Elvis(); private Elvis() { ... } public static Elvis getInstance() { return INSTANCE; } public void leaveTheBuilding() { ... }}3, 单元素的枚举类型已经成为实现Singleton最佳方法public enum Elvis { INSTANCE; public void leaveTheBuilding() { ... }}四,通过私有构造器强化不可实例化的能力只包含静态方法和静态域的工具类(utility class)实例对它没任何意义,只要让这个类构造器私有就可以保证不会被实例化。public class UtilityClass { private UtilityClass() { throw new AssertionError(); }副作用:这个类不能被继承。所有的构造器都必须显示或隐式地调用超类的构造器。五,避免创建不必要的对象构造器在每次被调用时都会创建一个新的对象。可以使用静态工厂方法代替构造器,以避免创建不必要的对象。例:Boolean.valueOf(String)。静态初始化,只需初始化一次。延迟初始化。六,消除过期的对象引用只要是类是自己管理内存,程序员就应该警惕内存泄漏。七,比用使用终结方法终结方法(finalizer)通常是不可以预测的,也是很危险的。终结方法的缺点在于不能保证会被及时地执行。在C++中,析构器是回收一个对象所占资源的常规方法。Java中,一般用try-finally完成类似的工作。第三章 对于所有对象都通用的方法八,覆盖equals时请遵守通用约定==比较的是引用,equals比较的是值!九,覆盖equals时总要覆盖hashcode@Override public boolean equals(Object O) { ... }@Override public int hashCode() { ... }相等的(equals)的对象必须具有相等的hash code。不相等的两个对象,hash code有可能相等。Eclispe提供了代码生成工具(Source->Generates hashCode() and equals()...)十,始终要覆盖toString@Override public String toString() { ... }十一,谨慎地覆盖clone()方法public interface Cloneable { } 如果一个类实现了Cloneable,Object的clone方法就会返回该对象的逐域拷贝,否则就会抛出CloneNotSupportedException.clone()就是另一个构造器;你必须确保它不会伤害到原始的对象,并确保正确地创建被克隆对象中的约束条件。(深度拷贝,deep copy)无需调用构造器就可以创建对象。协变返回类型(covariant return type),override方法的返回类型可以是被覆盖方法返回类型的子类型。所有实现Cloneable接口的类都应该用一个公有方法覆盖clone。此方法首先调用super.clone(),然后clone自身域。@Override public Stack clone() { try { Stack result = (Stack)super.clone(); result.elements = elements.clone(); return result; } catch (CloneNotSupportedException e) { throw new AssertionError(); }}另一个实现对象拷贝的办法是提供一个拷贝构造器或拷贝工厂:public Yum(Yum yum) copy ctorpublic static Yum newInstance(Yum yum); copy factory十二,考虑实现Comparable接口类实现了Comparable接口,就表明它的实例具有内在的排序关系。public interface Comparable<T> { int compareTo(T t);} 当该对象小于、等于或大于指定对象的时候,分别返回一个负整数、零或正整数。第四章 类和接口十三, 使类和成员的可访问性最小化private, package-private, protected, public十四,在公有类中使用访问方法而非公有域十五,使可变性最小化十六,组合优先于继承实现继承(implementation inheritance), 接口继承(interface inheritance)组合(composition), 转发方法(forwarding method)包装类(wrapper class)-->Decorator模式十七,要么为继承而设计并提供文档说明,要么就禁止继承十八,接口优于抽象类抽象类允许包含某些方法的实现;接口不允许。为实现抽象类定义的类型,类必须成为抽象类的一个子类,Java只允许单继承;可以implement多个接口十九,接口只用于定义类型静态导入(static import):JUnit,ass ertEquals()二十,类层次优于标签类二十一,用函数对象表示策略class StringLengthComparator { public int compare(String s1, String s2) { return s1.length() - s2.length(); }} StringLengthComparator没有域是无状态的,因此非常适合成为Singleton。class StringLengthComparator { private StringLengthComparator() { } public static final StringLengthComparator INSTANCE = new StringLengthComparator(); public int compare(String s1, String s2) { return s1.length() - s2.length(); }}public interface Comparator<T> { public int compare(T t1, T t2);} Arrays.sort(stringArray, new Comparator<String>() { public int compare(String s1, String s2) { return s1.length() - s2.length(); }}; 可以将函数对象存储到一个私有的静态final域中,并重用。class Host { private static class StringLengthComparator implements Comparator<String>, Serializable { public int compare(String s1, String s2) { return s1.length() - s2.length(); } } public static final Comparator<String> STRING_LENGTH_COMPARATOR = new StringLengthComparator(); //.....} 函数指针的主要用途就是实现策略(Strategy)模式。Java中声明一个接口表示策略,并且为每个具体策略声明一个实现了该接口的类。例:Arrays.sort(array, comparator);二十二,优先考虑静态成员类嵌套类有四种:静态成员类,非静态成员类,匿名类,局部类。非静态成员类的每个实例都隐含着与一个外围实例相关联匿名类一种常见用法是动态地创建函数对象;另一种用法是创建过程对象,比如Runnable,Thread或者TimerTask实例;第三种常见的用法是在静态工厂方法的内部。第五章 泛型二十三,不要在新代码中使用原生态类型二十四,消除非受检警告@SuppressWarnings("unchecked")二十五,List优先于数组二十六,优先考虑泛型二十七,优先考虑泛型方法二十八,利用有限制通配符来提升API的灵活性二十九,优先考虑类型安全的异构容器第六章 枚举和注解三十,用enum代替int常量三十一,用实例域代替序数public enum Ensemble { SOLO(1), DUET(2), TRIO(3), QUARTET(4); private final int numberOfMusicians; Ensemble(int size) { this.numberOfMusicians = size; } public int numberOfMusicians() { return numberOfMusicians; }} 三十二,用EnumSet代替位域三十三,用EnumMap代替序数索引三十四,用接口模拟可伸缩的枚举三十五,注解优先于命名模式三十六,坚持用Override注解三十七,用标记接口定义类型标记接口(marker interface)是没有包含方法声明的接口。例:Serializable第七章 方法三十八,检查参数有效性在方法体得开头处检查参数。三十九,必要时进行保护性拷贝四十,谨慎设计方法签名谨慎选择方法名;避免过长参数列表;参数类型优先使用接口而非具体类;对于boolean参数,优先使用两个元素的枚举类型:public enum TemperatureScale { FAHRENHEIT, CELSIUS }四十一,慎用重载overload方法的选择是静态的,overridden方法的选择是动态。四十二,慎用可变参数四十三,返回零长度的数组或者集合而不是nullCollections.emptySet, emptyList, emptyMapprivate final List<Cheese> cheesesInStock = ...;public List<Cheese> getCheeseList() { if (cheeseInStock.isEmpty()) return Collections.emptyList(); else return new ArrayList<Cheese>(cheeseInStock); }} 四十四,为所有导出的API元素编写文档注释第八章 通用程序设计四十五,将局部变量的作用域最小化四十六,for-each循环优先于传统的for循环for (Iterator i = c.iterator(); i.hasNext(); ) { doSomething((Element)i.next()); // i.remove();}public interface Iterable<E> { Iterator<E> iterator();}三种情况下无法使用for-each循环:过滤,转换,平行迭代。 四十七,了解和使用类库java.lang.*, java.util.*, Collections Framework四十八,如果需要精确的答案,请避免使用float和doubleBigDecimal四十九,基本类型优先于装箱类型永远不要用==做相等测试!Object.equals(object);五十,如果其他类型更适合,则避免使用字符串五十一,需要连接字符串时,用StringBuilder代替String五十二,优先使用接口而非类来引用对象五十三,接口优先于反射机制五十四,谨慎地使用本地方法五十五,谨慎地进行优化必须在设计时考虑性能问题;使用性能剖析工具探测性能瓶颈五十六,遵守普遍接受的命名惯例第九章 异常五十七,只针对异常的情况才使用异常五十八,对可恢复的情况使用受检情况,对编程错误使用运行时异常五十九,避免不必要地使用受检的异常六十,优先使用标准的异常六十一,抛出与抽象相对应的异常六十二,每个方法抛出的异常都要有文档六十三,在细节消息中包含能捕获失败的信息六十四,努力使失败保持原子性六十五,不要忽略异常第十章 并发六十六,同步访问共享的可变数据六十七,避免过度同步六十八,executor和task优先于线程六十九,并发工具优先于wait和notify七十,线程安全性的文档化七十一,延迟延迟初始化七十二,不要依赖于线程调度器七十三,避免使用线程组第十一章 序列化七十四,谨慎地实现Serializable接口七十五,考虑使用自定义的序列化形式七十六,保护性地编写readObject方法七十七,对于实例控制,枚举类型优先于readResolve七十八,考虑用序列化代理代替序列化实例 (收起)2011-05-15 20:19:24 回应
-
第174页
返回长度为0的数组或集合,而不是null。 这样可以让客户端程序省去做null判断的麻烦。也在一定程度上避免了NullPointException 。但有时候,客户端检查数组length==0或集合isEmpty()不可避免的。 可以用Collections的emptyList() emptySet() 和 emptyMap()返回对应的空集合。 (更多)
这样可以让客户端程序省去做null判断的麻烦。也在一定程度上避免了NullPointException。但有时候,客户端检查数组length==0或集合isEmpty()不可避免的。可以用Collections的emptyList() emptySet() 和 emptyMap()返回对应的空集合。 (收起)返回长度为0的数组或集合,而不是null。
2012-01-17 10:58:10 回应
-
第171页
数组继承了Object的toString方法,所以直接在数组上调用toString会产生诸如[Ljava.lang.Ingeger;@3e25e]这样的没有意义的字符串。为了打印出符合预期的字符串,方法如下: 废弃的做法: /代码内容已省略/ 这种方式只对引用类型数组有效,对基本数据类型数组则无法编译。 正确的做法: /代码内容已省略/ (更多)数组继承了Object的toString方法,所以直接在数组上调用toString会产生诸如[Ljava.lang.Ingeger;@3e25e]这样的没有意义的字符串。为了打印出符合预期的字符串,方法如下:废弃的做法:System.out.println(Arrays.asList(myArray));
这种方式只对引用类型数组有效,对基本数据类型数组则无法编译。正确的做法:System.out.println(Arrays.toString(myArray));
(收起)2012-01-13 10:37:35 回应
-
第1页
Wuqifu (喜欢买书的软件工程师~)
本想给这本书4星的,因为感觉没有Scott Meyers的《Effective C++》、《More Effective C++》、《Effective STL》系列写得好;考虑到Java学习上只此一本《Effective Java》还是给5星吧。毕竟这本书也还是很值得一读的! 抄录一些笔记,空白的条目表示没看明白,以后有新的理解再补充。 第一章 引言 一, 代码应该被重用,而不是被拷贝。 第二章 创建和销毁对象 一,考虑用静态工厂方法代替构造器 public static Boolean v... (更多)本想给这本书4星的,因为感觉没有Scott Meyers的《Effective C++》、《More Effective C++》、《Effective STL》系列写得好;考虑到Java学习上只此一本《Effective Java》还是给5星吧。毕竟这本书也还是很值得一读的!抄录一些笔记,空白的条目表示没看明白,以后有新的理解再补充。第一章 引言一, 代码应该被重用,而不是被拷贝。第二章 创建和销毁对象一,考虑用静态工厂方法代替构造器public static Boolean valueOf(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE;} 静态工厂方法能够为重复的调用返回相同的对象。静态工厂惯用名称:valueOf, of, getInstance, newInstance, getType, newType.二, 遇到多个构造器参数时要考虑用builder三,用私有构造器或者枚举类型强化Singleton属性1,public class Elvis { public static final Elvis INSTANCE = new Elvis(); private Elvis() { .... } public void leaveTheBuilding() {...}}2, public class Elvis { private static final Elvis INSTANCE = new Elvis(); private Elvis() { ... } public static Elvis getInstance() { return INSTANCE; } public void leaveTheBuilding() { ... }}3, 单元素的枚举类型已经成为实现Singleton最佳方法public enum Elvis { INSTANCE; public void leaveTheBuilding() { ... }}四,通过私有构造器强化不可实例化的能力只包含静态方法和静态域的工具类(utility class)实例对它没任何意义,只要让这个类构造器私有就可以保证不会被实例化。public class UtilityClass { private UtilityClass() { throw new AssertionError(); }副作用:这个类不能被继承。所有的构造器都必须显示或隐式地调用超类的构造器。五,避免创建不必要的对象构造器在每次被调用时都会创建一个新的对象。可以使用静态工厂方法代替构造器,以避免创建不必要的对象。例:Boolean.valueOf(String)。静态初始化,只需初始化一次。延迟初始化。六,消除过期的对象引用只要是类是自己管理内存,程序员就应该警惕内存泄漏。七,比用使用终结方法终结方法(finalizer)通常是不可以预测的,也是很危险的。终结方法的缺点在于不能保证会被及时地执行。在C++中,析构器是回收一个对象所占资源的常规方法。Java中,一般用try-finally完成类似的工作。第三章 对于所有对象都通用的方法八,覆盖equals时请遵守通用约定==比较的是引用,equals比较的是值!九,覆盖equals时总要覆盖hashcode@Override public boolean equals(Object O) { ... }@Override public int hashCode() { ... }相等的(equals)的对象必须具有相等的hash code。不相等的两个对象,hash code有可能相等。Eclispe提供了代码生成工具(Source->Generates hashCode() and equals()...)十,始终要覆盖toString@Override public String toString() { ... }十一,谨慎地覆盖clone()方法public interface Cloneable { } 如果一个类实现了Cloneable,Object的clone方法就会返回该对象的逐域拷贝,否则就会抛出CloneNotSupportedException.clone()就是另一个构造器;你必须确保它不会伤害到原始的对象,并确保正确地创建被克隆对象中的约束条件。(深度拷贝,deep copy)无需调用构造器就可以创建对象。协变返回类型(covariant return type),override方法的返回类型可以是被覆盖方法返回类型的子类型。所有实现Cloneable接口的类都应该用一个公有方法覆盖clone。此方法首先调用super.clone(),然后clone自身域。@Override public Stack clone() { try { Stack result = (Stack)super.clone(); result.elements = elements.clone(); return result; } catch (CloneNotSupportedException e) { throw new AssertionError(); }}另一个实现对象拷贝的办法是提供一个拷贝构造器或拷贝工厂:public Yum(Yum yum) copy ctorpublic static Yum newInstance(Yum yum); copy factory十二,考虑实现Comparable接口类实现了Comparable接口,就表明它的实例具有内在的排序关系。public interface Comparable<T> { int compareTo(T t);} 当该对象小于、等于或大于指定对象的时候,分别返回一个负整数、零或正整数。第四章 类和接口十三, 使类和成员的可访问性最小化private, package-private, protected, public十四,在公有类中使用访问方法而非公有域十五,使可变性最小化十六,组合优先于继承实现继承(implementation inheritance), 接口继承(interface inheritance)组合(composition), 转发方法(forwarding method)包装类(wrapper class)-->Decorator模式十七,要么为继承而设计并提供文档说明,要么就禁止继承十八,接口优于抽象类抽象类允许包含某些方法的实现;接口不允许。为实现抽象类定义的类型,类必须成为抽象类的一个子类,Java只允许单继承;可以implement多个接口十九,接口只用于定义类型静态导入(static import):JUnit,ass ertEquals()二十,类层次优于标签类二十一,用函数对象表示策略class StringLengthComparator { public int compare(String s1, String s2) { return s1.length() - s2.length(); }} StringLengthComparator没有域是无状态的,因此非常适合成为Singleton。class StringLengthComparator { private StringLengthComparator() { } public static final StringLengthComparator INSTANCE = new StringLengthComparator(); public int compare(String s1, String s2) { return s1.length() - s2.length(); }}public interface Comparator<T> { public int compare(T t1, T t2);} Arrays.sort(stringArray, new Comparator<String>() { public int compare(String s1, String s2) { return s1.length() - s2.length(); }}; 可以将函数对象存储到一个私有的静态final域中,并重用。class Host { private static class StringLengthComparator implements Comparator<String>, Serializable { public int compare(String s1, String s2) { return s1.length() - s2.length(); } } public static final Comparator<String> STRING_LENGTH_COMPARATOR = new StringLengthComparator(); //.....} 函数指针的主要用途就是实现策略(Strategy)模式。Java中声明一个接口表示策略,并且为每个具体策略声明一个实现了该接口的类。例:Arrays.sort(array, comparator);二十二,优先考虑静态成员类嵌套类有四种:静态成员类,非静态成员类,匿名类,局部类。非静态成员类的每个实例都隐含着与一个外围实例相关联匿名类一种常见用法是动态地创建函数对象;另一种用法是创建过程对象,比如Runnable,Thread或者TimerTask实例;第三种常见的用法是在静态工厂方法的内部。第五章 泛型二十三,不要在新代码中使用原生态类型二十四,消除非受检警告@SuppressWarnings("unchecked")二十五,List优先于数组二十六,优先考虑泛型二十七,优先考虑泛型方法二十八,利用有限制通配符来提升API的灵活性二十九,优先考虑类型安全的异构容器第六章 枚举和注解三十,用enum代替int常量三十一,用实例域代替序数public enum Ensemble { SOLO(1), DUET(2), TRIO(3), QUARTET(4); private final int numberOfMusicians; Ensemble(int size) { this.numberOfMusicians = size; } public int numberOfMusicians() { return numberOfMusicians; }} 三十二,用EnumSet代替位域三十三,用EnumMap代替序数索引三十四,用接口模拟可伸缩的枚举三十五,注解优先于命名模式三十六,坚持用Override注解三十七,用标记接口定义类型标记接口(marker interface)是没有包含方法声明的接口。例:Serializable第七章 方法三十八,检查参数有效性在方法体得开头处检查参数。三十九,必要时进行保护性拷贝四十,谨慎设计方法签名谨慎选择方法名;避免过长参数列表;参数类型优先使用接口而非具体类;对于boolean参数,优先使用两个元素的枚举类型:public enum TemperatureScale { FAHRENHEIT, CELSIUS }四十一,慎用重载overload方法的选择是静态的,overridden方法的选择是动态。四十二,慎用可变参数四十三,返回零长度的数组或者集合而不是nullCollections.emptySet, emptyList, emptyMapprivate final List<Cheese> cheesesInStock = ...;public List<Cheese> getCheeseList() { if (cheeseInStock.isEmpty()) return Collections.emptyList(); else return new ArrayList<Cheese>(cheeseInStock); }} 四十四,为所有导出的API元素编写文档注释第八章 通用程序设计四十五,将局部变量的作用域最小化四十六,for-each循环优先于传统的for循环for (Iterator i = c.iterator(); i.hasNext(); ) { doSomething((Element)i.next()); // i.remove();}public interface Iterable<E> { Iterator<E> iterator();}三种情况下无法使用for-each循环:过滤,转换,平行迭代。 四十七,了解和使用类库java.lang.*, java.util.*, Collections Framework四十八,如果需要精确的答案,请避免使用float和doubleBigDecimal四十九,基本类型优先于装箱类型永远不要用==做相等测试!Object.equals(object);五十,如果其他类型更适合,则避免使用字符串五十一,需要连接字符串时,用StringBuilder代替String五十二,优先使用接口而非类来引用对象五十三,接口优先于反射机制五十四,谨慎地使用本地方法五十五,谨慎地进行优化必须在设计时考虑性能问题;使用性能剖析工具探测性能瓶颈五十六,遵守普遍接受的命名惯例第九章 异常五十七,只针对异常的情况才使用异常五十八,对可恢复的情况使用受检情况,对编程错误使用运行时异常五十九,避免不必要地使用受检的异常六十,优先使用标准的异常六十一,抛出与抽象相对应的异常六十二,每个方法抛出的异常都要有文档六十三,在细节消息中包含能捕获失败的信息六十四,努力使失败保持原子性六十五,不要忽略异常第十章 并发六十六,同步访问共享的可变数据六十七,避免过度同步六十八,executor和task优先于线程六十九,并发工具优先于wait和notify七十,线程安全性的文档化七十一,延迟延迟初始化七十二,不要依赖于线程调度器七十三,避免使用线程组第十一章 序列化七十四,谨慎地实现Serializable接口七十五,考虑使用自定义的序列化形式七十六,保护性地编写readObject方法七十七,对于实例控制,枚举类型优先于readResolve七十八,考虑用序列化代理代替序列化实例 (收起)2011-05-15 20:19:24 回应
-
第174页
返回长度为0的数组或集合,而不是null。 这样可以让客户端程序省去做null判断的麻烦。也在一定程度上避免了NullPointException 。但有时候,客户端检查数组length==0或集合isEmpty()不可避免的。 可以用Collections的emptyList() emptySet() 和 emptyMap()返回对应的空集合。 (更多)
这样可以让客户端程序省去做null判断的麻烦。也在一定程度上避免了NullPointException。但有时候,客户端检查数组length==0或集合isEmpty()不可避免的。可以用Collections的emptyList() emptySet() 和 emptyMap()返回对应的空集合。 (收起)返回长度为0的数组或集合,而不是null。
2012-01-17 10:58:10 回应
-
第171页
数组继承了Object的toString方法,所以直接在数组上调用toString会产生诸如[Ljava.lang.Ingeger;@3e25e]这样的没有意义的字符串。为了打印出符合预期的字符串,方法如下: 废弃的做法: /代码内容已省略/ 这种方式只对引用类型数组有效,对基本数据类型数组则无法编译。 正确的做法: /代码内容已省略/ (更多)数组继承了Object的toString方法,所以直接在数组上调用toString会产生诸如[Ljava.lang.Ingeger;@3e25e]这样的没有意义的字符串。为了打印出符合预期的字符串,方法如下:废弃的做法:System.out.println(Arrays.asList(myArray));
这种方式只对引用类型数组有效,对基本数据类型数组则无法编译。正确的做法:System.out.println(Arrays.toString(myArray));
(收起)2012-01-13 10:37:35 回应
-
第170页
可变参数方法有两个特征: 1、参数是0个到多个 2、参数最终会以数组的方法传递给方法 问题: 1、我们经常需要的1个到多个的参数 2、每次调用可变参数方法会有一次数组分配和初始化,可能影响性能 解决方法: 1、显式的声明一个参数,后面再跟一个可变参数。例如: /代码内容已省略/ 2、如果一定要提高性能,且确定对这个方法95%的调用会有3个或更少的参数,就.. (更多)可变参数方法有两个特征: 1、参数是0个到多个 2、参数最终会以数组的方法传递给方法问题: 1、我们经常需要的1个到多个的参数 2、每次调用可变参数方法会有一次数组分配和初始化,可能影响性能解决方法: 1、显式的声明一个参数,后面再跟一个可变参数。例如:static int min(int firstArg, int... remainingArgs){ int min = firstArg; for(int arg : remainingArgs){ if(arg < min) { min = arg; } } return min; }2、如果一定要提高性能,且确定对这个方法95%的调用会有3个或更少的参数,就声明5个重载。例如:public void foo(){} public void foo(int a1){} public void foo(int a1, int a2){} public void foo(int a1, int a2, int a3){} public void foo(int a1, int a2, int a3, int... rest){}这样有95%的调用都是调用的确定参数的重载方法,只有5%的调用会用到性能相对较低的可变参数方法。但是值得注意的是,这种方式又是优雅。除非必要。不要使用。 (收起)2012-01-13 10:19:26 回应
书评 · · · · · · (共24条) 我来评论这本书
热门评论 最新评论
Java程序员进阶必看书籍
-
- Kenny小狼(﹎.大丈夫だ、問題ない.﹎) 《Effective Java》是一本什么样的作品,相信也不用我去多阐述了,网上大堆的评价。而刚刚听到这本书的朋友们都应该是被朋友推荐所以才看的。 说回自己的感想,无论这本中文版纸质如何,也只能说对于英语水平不高的朋友们的唯一选择。但也这样说吧,在没得选择的情况下我才会看这本书。 另外,看这本书的朋友就如作......2009-09-13 7/8有用
Java的进阶书籍
-
- 行者 SixSun Java的进阶书籍,页数比起Thinking in Java就显得单薄了(不过至今没有全部看完),57条极具实用价值的经验规则,让你对Java细节有更深入的了解。除此之外像Java 深度歷險電子版 也很不错,台湾作家moli写的一本书,有一些关于Java虚拟机的知识,通俗易懂的解释和实例让你对类的加载有一个初步的认识。......2007-12-19 4/4有用来自 机械工业出版社2003版
如何设计才是核心所在
-
- 邱伟 很薄的一本,却很是经典。收获不在于如何高效编写Java程序,而是如何去思考去设计一个类库。 那些Java发展的逸事与失误,比其成功更能让人有所得。 ......2012-01-06 来自 机械工业出版社2003版
如何设计才是核心所在
-
- 邱伟 很薄的一本,却很是经典。收获不在于如何高效编写Java程序,而是如何去思考去设计一个类库。 那些Java发展的逸事与失误,比其成功更能让人有所得。 ......2012-01-06 来自 机械工业出版社2003版
入木三分
-
- froglv 很早就读过,当时就知道这本书很好,可惜当时功力尚浅,没什么收获。但近日再读时,确实很有收获,可以说此书虽不是深入骨髓,但也算入木三分。新手勿动!...... (5回应)2007-02-02 5/8有用来自 机械工业出版社2003版
推荐一下!
-
- become 光买了书,唉没时间看书啊!我电脑Z差啊,学得头都大了啊!还好,室友告诉我上猎豹网校,看那个视频课程学。嘿嘿,这是个简单容易的办法!这下不再担心买了书,束之高阁了! ......2011-12-12 来自 机械工业出版社2003版
Effective Java Programming Language Guide
-
- 涅瓦纳(一个沉默的观影者与读书人) Effective Java Programming Language Guide distills the hard-won wisdom of today's best Java programmers into 50 techniques for designing and constructing more r......2011-07-30 来自 Addison-Wesley Professional版
每个java程序员的案头应该有一本
-
- 疯狂的菠菜(菠菜也疯狂) 读第一版已经是好几年前的事儿了, 现在想起来也没什么印象, 也没什么收获, 估计那会儿刚接触java, 还是个菜鸟, 很多东东都不甚了解. 虽然一直在用java, 不过大部分都是用一些很常见的东西, 其实java还有很多细节和技巧值得我们去发掘和实践, 而这些内容却能真正体现一个人的Java水平. 看第二版收获非常多,......2011-07-02
"Effective Java中文版"的论坛 · · · · · ·
| Effective Java Second Edition中文版勘误列表专用贴 | 来自YuLimin | 1 回应 | 2011-05-04 |
| 极品 | 来自半兽人 | 2010-11-03 | |
| 即使看过第一版也值得再看第二版 | 来自我有分寸 | 2010-10-25 | |
| 如何写出符合Java特性的代码?如何写出符合英语特性的... | 来自Bourne | 1 回应 | 2010-08-23 |
| 不敢说翻译的不好,仅因为纸质差,我还是看原版吧 | 来自JohnTang | 2010-06-24 |
> 浏览更多话题
这本书的其他版本 · · · · · · ( 全部6 )
- Addison-Wesley Professional版 05 June, 2001 / 116人读过 / 有售
- 机械工业出版社版 2003-1-1 / 870人读过
- 未知出版社版 2009-9 / 19人读过 / 有售
- 中国电力出版社版 2003-11-01 / 18人读过
以下豆列推荐 · · · · · · (全部)
- Java修炼之道 (威廉他)
- Java好书 (滑板)
- 2009读书 (r2g2)
- Sleepless in Java (谐音太郎)
- Ing.Informatica (Welch)
谁读这本书?
喜欢这本书的人常去的小组 · · · · · ·

- NoSQL (900)

- Java&Android移动应用编程 (5515)

- Hadoop China (891)

- Thinking In Java (2143)

- 设计模式 (912)

- eclipse (3266)

- china-pub网上书店 (778)

- 程序员书屋 (6498)
喜欢这本书的人关注的活动 · · · · · ·
订阅关于Effective Java中文版的评论:
feed: rss 2.0











