标签: effective-java

Java序列化

我怀疑我遇到过阅读Effective Java.如果它是一个真正简单而直截了当的疑问,我道歉.因此,在第74项 - 明智地实施Serializable中,他说,即使在使用私有和私有领域实施一个好的信息隐藏在你的班级之后,它也很容易失去效力?无论我过去阅读过什么,所有序列化都是将对象转换为字节流形式,反序列化后保留相同的对象.如何在此过程中丢失数据隐藏?

java serialization effective-java

6
推荐指数
1
解决办法
624
查看次数

为什么在执行双重检查锁定时将volatile字段复制到局部变量

我正在阅读关于双重检查锁定的信息Effective Java.代码执行以下操作:

private volatile FieldType field;  
FieldType getField() {  
    FieldType result = field;  
    if (result == null) { // First check (no locking)  
        synchronized(this) {   
        result = field;  
        if (result == null) // Second check (with locking)  
            field = result = computeFieldValue();  
        }  
    }  
    return result;  
}    
Run Code Online (Sandbox Code Playgroud)

它说使用result似乎不需要但实际上确保field只在已经初始化的常见情况下只读取一次.

但我不明白这一点.与if(field == null)直接做什么有什么区别?我不明白为什么if (result == null)会有所不同,更不用说如上所述了.

java concurrency multithreading synchronization effective-java

5
推荐指数
2
解决办法
410
查看次数

有效的java项目编号74(关于序列化):明智地实现Serializable

有效的java书的第74号项目有一个段落(项目74的最后一个第2段),如下所述:

内部类(第22项)不应实现Serializable.它们使用编译器生成的合成字段来存储对封闭实例的引用,并存储来自封闭范围的局部变量的值.这些字段如何对应于类定义是未指定的,匿名和本地类的名​​称也是如此. 因此,内部类的默认序列化形式是不明确的.

我知道内部类使用编译器生成的合成字段来存储对封闭实例的引用,例如,如果封闭类是MyEnclosing而内部类是MyInner,则封闭引用是MyEnclosing.this.但我无法获得BOLD部分.请帮我理解意思.谢谢!!!

java effective-java

5
推荐指数
1
解决办法
1020
查看次数

如果我在Java中覆盖“等于”方法,为什么需要覆盖哈希码?

我知道只要equals在Java中重写该方法,就需要重写哈希码。那仅仅是合同。我试图了解其背后的逻辑。我正在阅读Joshua Bloch的 * Effective Java ,发现了以下代码(第9页,第45页):

import java.util.HashMap;
import java.util.Map;

public final class PhoneNumber {
    private final short areaCode;
    private final short prefix;
    private final short lineNumber;

    public PhoneNumber(int areaCode, int prefix, int lineNumber) {
        rangeCheck(areaCode, 999, "area code");
        rangeCheck(prefix, 999, "prefix");
        rangeCheck(lineNumber, 9999, "line number");
        this.areaCode = (short) areaCode;
        this.prefix = (short) prefix;
        this.lineNumber = (short) lineNumber;
    }

    private static void rangeCheck(int arg, int max, String name) {
        if (arg < 0 || arg > max) …
Run Code Online (Sandbox Code Playgroud)

java equals object hashcode effective-java

5
推荐指数
1
解决办法
4903
查看次数

hashCode中的按位运算符>>>

我有两个相关的问题:

  1. 按位运算符>>>表示我们正在将二进制数转移多个位置,同时在最高位填充0.但是,为什么以下操作产生相同的数字:5 >>> 32产生5和-5 >>> 32产生-5.因为如果上面的描述是正确的,那么这两个操作都会产生0作为最终结果.

  2. 在上面的继续中,根据Effective Java book,我们应该在计算哈希码时使用(int)(f ^(f >>> 32))(如果字段很长)(如果字段很长).为什么我们这样做,解释是什么

java hashcode bitwise-operators gethashcode effective-java

5
推荐指数
1
解决办法
2732
查看次数

转发类示例

阅读Effective Java,我从Item 16: Favor composition over inheritance.

在下面InstrumentedSet,这本书显示我们可以跟踪元素被插入的次数(通过InstrumentedSet.addCount变量)。

要做到这一点,我们可以简单地附加到这个类对象的addCount,然后调用ForwardingSet.add(),它调用实际Set类的 实际实现add()

// Reusable forwarding class 
public class ForwardingSet<E> implements Set<E> {     
  private final Set<E> s;     
  public ForwardingSet(Set<E> s) { this.s = s; }     
  public void clear()               { s.clear();            }    
  public boolean contains(Object o) { return s.contains(o); }
...
}

// Wrapper class - uses composition in place of inheritance   
public class InstrumentedSet<E> extends ForwardingSet<E> { …
Run Code Online (Sandbox Code Playgroud)

java effective-java

5
推荐指数
1
解决办法
4505
查看次数

JavaBean的缺点——构造过程中不一致

有效的 Java - Item-2 指出

JavaBean 在其构造过程中可能会处于不一致的状态。

我无法理解这一点,如果在方法中构造一个对象,那么它会如何不一致,如果必须发生异常,那么也可能在构造函数中发生。这与线程有何关系?

java effective-java

5
推荐指数
1
解决办法
853
查看次数

这个Java Puzzlers代码有什么问题?

在新的第三版Effective Java中,Joshua Bloch提到了Java Puzzlers的一段代码(它是关于在try-finally中关闭资源):

对于初学者来说,我在Java Puzzlers的第88页上弄错了,多年来没有人注意到.事实上,2007年Java库中close方法的三分之二使用是错误的.

但我不确定哪个部分错了?

} finally {
  if (in != null) {
    try {
      in.close();
    } catch (IOException ex) {
      // There is nothing we can do if close fails
    }
  }
  if (out != null) {
    try {
      out.close();
    } catch (IOException ex) {
      // Again, there is nothing we can do if close fails
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

这是此代码的新版本:

try {
  OutputStream out = new FileOutputStream(dst);
  try {
    byte[] buf = new byte[BUFFER_SIZE];
    int n;
    while …
Run Code Online (Sandbox Code Playgroud)

java try-catch try-catch-finally try-finally effective-java

5
推荐指数
1
解决办法
274
查看次数

为什么使用 javadoc 无参数构造函数?

在《Effective Java》(第三版)第 56 条中,Joshua Bloch 指出:“公共类不应该使用默认构造函数,因为没有办法为它们提供文档注释。”

默认构造函数不会做任何意外的事情,但它只是创建一个新实例。什么样的信息应该记录在无参数构造函数的文档注释中,而这些信息不应该只存在于类注释中?

如果一个类在初始化块中具有有趣的行为(因为否则没有地方可以对它们进行注释),或者甚至是字段的非标准值分配(可能调用方法来获取初始值),我可以理解这样做。但对于大多数课程来说,这似乎并没有增加太多。我有什么遗漏的吗?

java default-constructor effective-java

5
推荐指数
1
解决办法
3174
查看次数

Java 保留类型名称“var”最佳实践?

不幸的是,Effective Java 中没有任何文章讨论保留类型名称“var”(因为它是在 java 10 中引入的)。

有一种说法是,尽可能使用接口作为类型(条款 64:通过接口引用对象)。但是使用时var

var list = new ArrayList<String>(); // infers ArrayList<String>

list属于类型ArrayList<String>

《Effective Java》指出,通过变量的实现来引用变量是一种不好的做法,因为它会使代码依赖于它。这只是我在代码中开始使用 var 时发现的一个烦恼。

问题:

使用保留类型名称“var”时是否有任何最佳实践?我什么时候应该使用它?我什么时候应该避免它?

java var effective-java java-10

5
推荐指数
0
解决办法
1303
查看次数