标签: effective-java

来自Effective Java的第9项(等于合同):示例是否正确?

Bloch的精彩书籍"Effective Java"指出,如果equals不对称,则Collections的行为contains是不确定的.

在他给出的例子中(通过下面的小修改再现),布洛赫说他看到了"假",但也可以看到真实或异常.

如果标准没有指定contains(Object o)检查e.equals(o)o.equals(e)集合中的每个项目以及前者是否已实现,则可以看到"true" .然而,Collections Javadoc明确指出它必须是后者(这是我观察到的).

所以我看到的唯一可能是"假"或可能是异常(但是字符串Javadoc似乎排除了后者).

我理解更广泛的观点,非对称性可能equals会导致集合之外的代码出现问题,但我不会在他引用的例子中看到它.

我错过了什么吗?

import java.util.List;
import java.util.ArrayList;

class CIString {
  private final String s;

  public CIString(String s) {
    this.s = s;
  }

  @Override public boolean equals( Object o ) {
    System.out.println("Calling CIString.equals from " + this.s );
    if ( o instanceof CIString) 
      return s.equalsIgnoreCase( ( (CIString) o).s);
    if ( o instanceof String) 
      return s.equalsIgnoreCase( (String) o ); …
Run Code Online (Sandbox Code Playgroud)

java collections effective-java

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

为什么许多Android API类都不是最终的,即使它们没有明确记录继承?

有效的Java(Joshua Bloch)第17项说:

"设计和文件或继承或禁止它"

然而,只是粗略地浏览Android API就会发现大多数API类都是非最终的; 这是确定的,如果它们也记录为(继承ViewActivity,例如).但是也有几个非final类,但是文档没有提到这些类的可继承性.只是一些任意的例子来说明我的观点:

  • 表示系统服务的类(WifiManager,NotificationManager...)
  • 实用类如UriMatcher.
  • 一些特定于硬件的类如Camera.

开放性和可扩展性是Android的哲学,这里的惯例是否反过来?意思是,可以假设所有 Android API类都被设计为继承(无论是明确记录还是其他); 除非宣布最后?

android effective-java

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

需要解释有效Java教科书中的哈希码示例

以下是第9项中的示例代码:

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

  @Override
  public int hashCode() {
    int result = 17;
    result = 31 * result + areaCode;
    result = 31 * result + prefix;
    result = 31 * result + lineNumber;
    return result;
  }
}
Run Code Online (Sandbox Code Playgroud)

Pg 48指出:"选择值31是因为它是一个奇数素数.如果它是偶数且乘法溢出,信息就会丢失,因为2的muiltiplication相当于移位."

我理解乘2的概念相当于位移.我也知道当我们将一个大数乘以一个大的奇素数时,我们仍会得到溢出(因此信息丢失).我没有得到的是为什么由大奇数素数乘法引起的信息丢失优于由大偶数乘法引起的信息丢失.

java hashcode effective-java

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

在try catch块中放置一些代码可以阻止JVM进行优化?

从Effective Java中的Exceptions章节:

将代码放在try-catch块中会禁止现有JVM实现可能执行的某些优化

try-catch块为什么以及如何阻止JVM优化?

java try-catch effective-java

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

Enum类型,如Joshua Bloch在Effective Java中所述

请看这个链接.关于Enums,布洛赫先生说

Java的枚举类型是通过公共静态最终字段为每个枚举常量导出一个实例的类.

我阅读了Enum类文档,没有公共静态final字段,那么上述语句如何成立.请解释.谢谢

java enums effective-java

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

为什么UnaryFunction <Object>可以转换为UnaryFunction <T>?

当我阅读有效Java项目27时,类型之间的投射UnaryFunction<Object>UnaryFunction<T>困惑我.

interface UnaryFunction<T> {
    T apply(T t);
}

public class Main {
    private static final UnaryFunction<Object>  IDENTITY = new UnaryFunction<Object>() {
        public Object apply(Object t) {
            return t;
        }
    };

    @SuppressWarnings("unchecked")
    public static <T> UnaryFunction<T> identityFunction() {
        return  (UnaryFunction<T>) IDENTITY;
    }

    public static void main(String ... args) {
        UnaryFunction<A> identityA = Main.identityFunction();
        A a = identityA.apply(new A());
    }

}

class A {}
Run Code Online (Sandbox Code Playgroud)

为什么UnaryFunction<Object>可以投入UnaryFunction<T>

我知道通用类型将在编译器之后被删除.因此,(UnaryFunction<T>) IDENTITY最终将(UnaryFunction<Object>) IDENTITY,这将在运行系统中工作. …

java generics effective-java

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

在 equals 和 hashcode 方法中使用自动生成的 Hibernate 实体对象的 id

可爱的equals和hashcode,所有的理论都在这里,也在这里

我已经决定在我的许多休眠实体/域对象中使用 equals() 和 hashcode() 中自动生成的 id。

但是,许多网站表示您永远不应该这样做,因为在比较或使用哈希码的过程中第一次将对象持久保存到数据库中的风险。

我的观点是,在大多数用例中,这比更改任何其他字段的可能性要小得多。

单个域对象在首次创建时会生成一次 id,而几乎所有其他字段在正常业务流程中都有机会被更改(甚至可以更改唯一的用户名……)。

在我的许多域对象中,唯一 id 几乎是唯一需要考虑的合适字段(人、地址、宠物、...客户等?组合字段是一个好主意,但从使用自动生成的 id,我认为,不是很好的建议。

我还缺少其他东西吗?

java hibernate equals hashcode effective-java

4
推荐指数
1
解决办法
2196
查看次数

你应该避免使用Guavas Ordering.usingToString()吗?

在阅读Joshua Bloch的"Effective Java"之后,这个问题得到了提示.特别是在第10项中,他认为解析对象的字符串表示并将其用于除了友好的打印输出/调试之外的任何事情都是不好的做法.原因是这样的使用"容易出错,导致脆弱的系统在您更改格式时会中断".对我而言,看起来Guava Ordering.usingToString()是一个例子.那么使用它是不好的做法吗?

java guava effective-java

4
推荐指数
1
解决办法
290
查看次数

生成器模式多个varargs

我正在阅读Joshua Bloch的"Effective Java",在第2项中,他提到了在构造函数中处理几个参数时使用Builder模式的优点.一切都很好,直到我看到传统构造函数和这个模式之间的多个var-args差异.所以,我有一些疑问:

  1. 构建器模式如何允许多个var-args?
  2. 为什么传统的构造函数只允许一个var-arg?(可能是因为如果存在多个var-args会导致歧义,当两者的定义数据类型相同时,但我不确定这是否是正确的原因.)

我在代码中没有使用var-args,但是我知道它们的用途.我仍然无法理解上述陈述背后的原因.任何帮助,将不胜感激.

java variadic-functions builder-pattern effective-java

4
推荐指数
1
解决办法
537
查看次数

终止一个对象是否与归零一样?

所以我一直在经历"Effective Java 2nd Ed".

在第7项中,他谈到不使用终结器,因为它们可能会导致很多问题.

但是,我们不是使用终结器,而是"提供一种显式终止方法",其中一个例子就是密切语句.我不明白什么是"终止声明,它们和终结者之间有什么区别?

我得出结论,终止一个对象就像归零一样,因此资源被释放.但我想我不太了解它的区别.所以我感谢任何帮助.

谢谢 !

java oop effective-java

4
推荐指数
1
解决办法
113
查看次数