Effective Java 3rd 条目22 仅仅定义类型时使用接口

当一个类实现一个接口时,这个接口起一个类型的作用,可以被用来引用这个类的实例。一个类实现了一个接口,应该因此说明一些事情:使用这个类的实例,一个类可以做什么。为任何其他目的而定义一个接口,都是不恰当的。
不符合这个检测的一种接口是所谓的常量接口(constant interface)。这样的接口不包含任何方法;它仅仅包含静态final域,每个域导出一个常量。使用这些常量的类实现这个接口,避免了用类名限定常量名的必要。如下是个例子:

// 常量接口反模式 - 不要使用! 
public interface PhysicalConstants {
    // 阿伏伽德罗常数 (1/mol)
    static final double AVOGADROS_NUMBER = 6.022_140_857e23;

    // 玻尔兹曼常数 (J/K) 
    static final double BOLTZMANN_CONSTANT = 1.380_648_52e-23;

    // 电荷质量 (kg) 
    static final double ELECTRON_MASS = 9.109_383_56e-31;
}

常量接口模式是接口的糟糕使用。一个类内部使用一些常数是实现细节。实现一个常数接口造成这个实现细节泄漏到这个类的导出API中。类实现了一个常量接口,对于这个类的用户来说是不重要的。事实上,它可能令他们困惑。更为糟糕的是,它代表着一种承诺:如果在以后的发布中这个类改变了以致于它不再需要使用这些常量,那么它仍旧必须实现这个接口来保证两者的兼容性。如果一个非final类实现了一个常量接口,那么他的所有子类将使得它们的命名空间被这个接口中的常量污染。

Java平台库中有许多常量接口,比如java.io.ObjectStreamConstants。这些接口应该看成异常情况,而不应该模仿。

如果你想导出常数,有许多合理的选择。如果常数是和已存类或者接口联系紧密,那么你应该添加它们到这个类或者接口。比如,所有数值原始装箱类,比如Integer和Double,导出MIN_VALUE和MAX_VALUE常量。如果常量最好看成是枚举类型的成员,那么你应该导出它们为enum类型(enum type)(条目34)。否则,你应该使用一个不可实例化的效用类(utility class)(条目4)导出常量。下面是早先表述的PhysicalConstants例子的效用类版本:

// 常量效用类 
package com.effectivejava.science;
public class PhysicalConstants { 
    private PhysicalConstants() { }// 防止实例化public static final double AVOGADROS_NUMBER = 6.022_140_857e23; 
    public static final double BOLTZMANN_CONST = 1.380_648_52e-23; 
    public static final double ELECTRON_MASS = 9.109_383_56e-31;

}

顺便提一下,注意到数值字面量中的下划线字符(_)的使用。下划线自从Java7以来就是合法的,它没有影响到数值字面量的值,但是如果谨慎使用,可以使得它们更容易阅读。如果浮点数包含了五个或者更多的连续数字,不管是否是确定的,考虑添加下划线到数值字面量。对于至少十个字面值,不管是整数的还是浮点数,你应该使用下划线划分字面值到三个数的组,它代表正的或者负的以一千的幂。

通常,效用类需要客户端使用类名限定常数名字,例如,PhysicalConstants.AVOGADROS_NUMBER。如果你大量使用效用类导出的常数,那么你应该通过使用静态导入(static import)功能避免使用类名限定常数:

// 通过静态导入避免限定常数 
import static com.effectivejava.science.PhysicalConstants.*;
public class Test { 
    double atoms(double mols) { 
        return AVOGADROS_NUMBER * mols; 
    } 
    ...
    // PhysicalConstants更多的使用证明静态导入是正当的
}

总之,接口应该只在定义类型时使用。它们不应该仅仅导出常量时使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值