教程集 www.jiaochengji.com
教程集 >  脚本编程  >  java  >  正文 Java 接口常量反模式及定义 Java 常量的教程

Java 接口常量反模式及定义 Java 常量的教程

发布时间:2016-10-17   编辑:jiaochengji.com
教程集为您提供Java 接口常量反模式及定义 Java 常量的教程等资源,欢迎您收藏本站,我们将为您提供最新的Java 接口常量反模式及定义 Java 常量的教程资源
本文章来为各位详细的介绍一篇关于Java 接口常量反模式及定义 Java 常量的教程的例子,希望例子能够对各位同学带来有效的帮助,具体如下。


初学 Java 的人很不经意间就会把常量定义在接口中,大概唯一的理由是接口不能实例化,而使用接口中定义的常量也是不用附着在实例上的。这主要还是 JDK 本身给我们做了很多这样的榜样, 如  java.io.ObjectStreamConstans,多是出现在 Enum 类型到来之前。

其实 Java 的接口常量是一种反模式,理由如下:

1. 接口是不能阻止被实现或继承的,也就是说子接口或实现中是能够覆盖掉常量的定义(重名),这样通过父,子接口(或实现) 去引用常量是可能不一致的
2. 同样的,由于被实现或继承,造成在继承树中可以用大量的接口, 类 或实例去引用 同一个常量,从而造成接口中定义的常量污染了命名空间。(Java 编译器竟然允许使用实例去引用类变量)
3. 接口暗含的意思是:它是需被实现的,代表着一种类型,它的公有成员是要被暴露的 API。而在接口中定义的常量说不上是 API

4. 这点有些重复,Java 允许通过子类去引用父类中定义的常量,各级对像实例去引用父类的常量,所以这会造成相当的混乱不堪。定义的常量不能保证单一的引用方式。

参见: Effective java 第 19 条: 接口只用于定义类型

既然接口中不适于定义常量,那么该在何处为常量安家呢?接口为 实现/继承 而生,如果放在类中,并且这个类是 final,且封闭掉构造方法就行。于是我们先前的接口常量定义

<pre class="brush:java;toolbar:false">public interface Gender {   public static final int MALE = 1;   public static final int FEMALE = 0; } 就变成了 public final class Gender {   private Gender() {   }     public static final int MALE = 1;   public static final int FEMALE = 0; }</pre>

这就是 JDK 的 java.nio.charset.StandardCharsets 的写法。

在封闭的 final 类中定义常量确实是前进了一大步。但上面那样定义变量还有个致命缺陷,假如某个方法希望接收 Gender 的 MALE 或 FEMALE,所以类型是 int,而实际你可以传入一个 3,于是这个方法可能傻眼了。也就是说这样定义常量没有边界限制。

如果是为了定义一些松散的常量值,是可以使用 final 型封闭的类,如

<pre class="brush:java;toolbar:false">public final class ConfigConstants {   private ConfigConstants() {   }     public static final String FILE_PATH = "/data/credentials.conf";   public static final int MAX_LIMIT = 100; } 如果要定义的多个常量值是同质的,那么最好的定义常量的方式应该是枚举(上面的例子是没理由用枚举了) public enum Gender {   MALE,    FEMALE }</pre><pre class="brush:java;toolbar:false">上面的定义实质就是一个继承了 java.lang.Enum 的 final 类,获得了 java.lang.Enum 中有用方法,并且直接被编译器禁止被实例化,它有有限的两个 Gender 型成员  MALE 和 FEMALE。Java 枚举原理详见: 通过反编译字节码来理解 Java 枚举</pre>

最简表述上面的 Gender  枚举是

<pre class="brush:java;toolbar:false">public final class Gender extends java.lang.Enum {   public static final Gender MALE;   public static final Gender FEMALE; }</pre>

我们也能看到 JDK 也倾向于用枚举来定义常量了,如 java.nio.file.StandardOpenOption。

这样对于接受 Gender 类型参数的方法就只能传入 MALE 或 FEMALE 了,不再有其他选项,这就是枚举的意义。

您可能感兴趣的文章:
Java 接口常量反模式及定义 Java 常量的教程
php程序员可以转java吗?
JDBC技术介绍 <转>
php和java有什么区别
php怎么传给java
java常量与变量的学习笔记
go 获取函数地址_Go语言基础--接口浅析
在php当中常量和变量的区别
经典Java线程面试题70道
php和java的优势

[关闭]
~ ~