- 写在前面的话
- 引言
- 第 1 章 对象入门
- 第 2 章 一切都是对象
- 第 3 章 控制程序流程
- 第 4 章 初始化和清除
- 第 5 章 隐藏实施过程
- 第 6 章 类再生
- 第 7 章 多形性
- 第 8 章 对象的容纳
- 第 9 章 违例差错控制
- 第 10 章 Java IO 系统
- 第 11 章 运行期类型鉴定
- 第 12 章 传递和返回对象
- 第 十三 章 创建窗口和程序片
- 第 14 章 多线程
- 第 15 章 网络编程
- 第 16 章 设计范式
- 第 17 章 项目
- 附录 A 使用非 JAVA 代码
- 附录 B 对比 C++和 Java
- 附录 C Java 编程规则
- 附录 D 性能
- 附录 E 关于垃圾收集的一些话
- 附录 F 推荐读物
7.5.3 常数分组
由于置入一个接口的所有字段都自动具有 static 和 final 属性,所以接口是对常数值进行分组的一个好工具,它具有与 C 或 C++的 enum 非常相似的效果。如下例所示:
//: Months.java // Using interfaces to create groups of constants package c07; public interface Months { int JANUARY = 1, FEBRUARY = 2, MARCH = 3, APRIL = 4, MAY = 5, JUNE = 6, JULY = 7, AUGUST = 8, SEPTEMBER = 9, OCTOBER = 10, NOVEMBER = 11, DECEMBER = 12; } ///:~
注意根据 Java 命名规则,拥有固定标识符的 static final 基本数据类型(亦即编译期常数)都全部采用大写字母(用下划线分隔单个标识符里的多个单词)。
接口中的字段会自动具备 public 属性,所以没必要专门指定。
现在,通过导入 c07.*或 c07.Months,我们可以从包的外部使用常数——就象对其他任何包进行的操作那样。此外,也可以用类似 Months.JANUARY 的表达式对值进行引用。当然,我们获得的只是一个 int,所以不象 C++的 enum 那样拥有额外的类型安全性。但与将数字强行编码(硬编码)到自己的程序中相比,这种(常用的)技术无疑已经是一个巨大的进步。我们通常把“硬编码”数字的行为称为“魔术数字”,它产生的代码是非常难以维护的。
如确实不想放弃额外的类型安全性,可构建象下面这样的一个类(注释①):
//: Month2.java // A more robust enumeration system package c07; public final class Month2 { private String name; private Month2(String nm) { name = nm; } public String toString() { return name; } public final static Month2 JAN = new Month2("January"), FEB = new Month2("February"), MAR = new Month2("March"), APR = new Month2("April"), MAY = new Month2("May"), JUN = new Month2("June"), JUL = new Month2("July"), AUG = new Month2("August"), SEP = new Month2("September"), OCT = new Month2("October"), NOV = new Month2("November"), DEC = new Month2("December"); public final static Month2[] month = { JAN, JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC }; public static void main(String[] args) { Month2 m = Month2.JAN; System.out.println(m); m = Month2.month[12]; System.out.println(m); System.out.println(m == Month2.DEC); System.out.println(m.equals(Month2.DEC)); } } ///:~
①:是 Rich Hoffarth 的一封 E-mail 触发了我这样编写程序的灵感。
这个类叫作 Month2,因为标准 Java 库里已经有一个 Month。它是一个 final 类,并含有一个 private 构建器,所以没有人能从它继承,或制作它的一个实例。唯一的实例就是那些 final static 对象,它们是在类本身内部创建的,包括:JAN,FEB,MAR 等等。这些对象也在 month 数组中使用,后者让我们能够按数字挑选月份,而不是按名字(注意数组中提供了一个多余的 JAN,使偏移量增加了 1,也使 December 确实成为 12 月)。在 main() 中,我们可注意到类型的安全性:m 是一个 Month2 对象,所以只能将其分配给 Month2。在前面的 Months.java 例子中,只提供了 int 值,所以本来想用来代表一个月份的 int 变量可能实际获得一个整数值,那样做可能不十分安全。
这儿介绍的方法也允许我们交换使用==或者 equals(),就象 main() 尾部展示的那样。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论