关于java 的常量接口的问题 新学JAVA,本来想声明一个接口,用于保存常用的静态常量,但在网上看到有人说:常量接口是用Java接口来声明一些常量,然后由实现这个接口的类使用这些常量。蛤建议不要模仿这种常量接口的做法。想必这样做不好,请各位老大指点一下! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 在接口里声明静态常量的实例,java.sql包里有很多,如ResultSet接口里有:static int CLOSE_CURSORS_AT_COMMIT 该常量指示调用 Connection.commit 方法时应该关闭 ResultSet 对象。 static int CONCUR_READ_ONLY 该常量指示不可以更新的 ResultSet 对象的并发模式。 static int CONCUR_UPDATABLE 该常量指示可以更新的 ResultSet 对象的并发模式。 static int FETCH_FORWARD 该常量指示将按正向(即从第一个到最后一个)处理结果集中的行。 static int FETCH_REVERSE 该常量指示将按反向(即从最后一个到第一个)处理结果集中的行处理。 static int FETCH_UNKNOWN 该常量指示结果集中的行的处理顺序未知。 static int HOLD_CURSORS_OVER_COMMIT 该常量指示调用 Connection.commit 方法时不应关闭 ResultSet 对象。 static int TYPE_FORWARD_ONLY 该常量指示指针只能向前移动的 ResultSet 对象的类型。 static int TYPE_SCROLL_INSENSITIVE 该常量指示可滚动但通常不受其他的更改影响的 ResultSet 对象的类型。 static int TYPE_SCROLL_SENSITIVE 该常量指示可滚动并且通常受其他的更改影响的 ResultSet 对象的类型。 我也有楼主同样的疑惑。我在阎宏博士的《JAVA与模式》一书中看到了这样的说法,认为使用常量接口是错误的行为,建议读者不要使用,但没有说明原因,有明白个中缘由的高手解释一下吧,谢谢! JAVA的接口常量(普通类型,如int or String)在JDK1.5之前基本是被用来模拟Enumeration的,她的最大缺点就是:当某个类或接口支持多组不同含义的常量组时,常量的使用常常陷入混乱,并写出可读性极差的代码,example: java.util.Calendar.class 代表与计算一个日期类型,拥有众多常量,==================================》For the date fields: (这一组是用来指定特定日期的常量字段) YEAR + MONTH + DAY_OF_MONTH YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK YEAR + DAY_OF_YEAR YEAR + DAY_OF_WEEK + WEEK_OF_YEAR==================================》For the time of day fields:(这一组是用来指定特定时间的常量字段) HOUR_OF_DAY HOUR + MINUTE + SECOND AM_PM + HOUR==================================》当设置年份时(Calendar.YEAR is 1),通常的做法是这样:Calendar calendar = Calendar.getInstance();int expectedYearValue = 2006;calendar.set(Calendar.YEAR, expectedYearValue);但是...你通常也可以这样Calendar calendar = Calendar.getInstance();int expectedYearValue = 2006;calendar.set(Calendar.PM, expectedYearValue);由于Calendar.PM 和 Calendar.YEAR常量的值相同(都为整型 1),所以这里互换之后编译器不会发出任何警报,事实上你依然赋值了YEAR字段,但是阅读代码的人却看的莫名其妙,一头雾水,她或他不得不深入代码细节去看个究竟,这里更本就不该有PM常量的身影,她本来更本不该作为这个方法的参数而存在...----------另一个麻烦在于硬编码,再比如上例的Calendar.set方法,她其中一个版本的完全申明如下:set(field: int, value: int) : voidfield字段如上个问题中一样是代表需要赋值的字段是什么,第二个字段则是需要赋予的值field字段本质上仅仅是一个int类型的变量(其他各种简单变量都可以,比如char, String, float...),所以你往往可以硬编码,比如我要赋值Year字段:int expectedYearValue = 2006;calendar.set(1, expectedYearValue);这里编译器不会爆任何错误,然后我们再改动一下calendar.set(999, expectedYearValue);编译器仍然认为是正确的,只有当进入运行时才会导致错误... ...编译器的强大功能被完全忽略和跳过了...这也可能会导致某种潜在的程序缺陷----所以综上所述,直接使用int, char or String...这些简单类型作为常量使用是不太明智的(除非这些类型确实正好体现了他们需要代表常量的类型,比如 static final int MAX_INT_VALUE = 999;)。如果使用的是JDK1.5版本或以上,可以直接是使用Enum类型来代替这些东西,Enum的静态类型检查会大大有助于提高程序的可读性和健壮性;如果很不幸的,你还必须使用JDK1.4或以下版本,比如我,可以参考《Effective Java》第5章21条,“用类来代替enum结构”,事实上JDK1.5中对Enum的模拟就是基于这种方式,只是将这种功能嵌入了语言特性中变成了语言的固有部分而已。@.@||~ 命名规则的一个问题 关于新JDK6UP14的安装问题 JAXP默认使用的是哪种XML解析器? 求教高人,有关java Socket连接的问题,长连接无法保持 请教大家一个关于数组参数间赋值的问题! 请教一个关于ROSE的问题?反向工程时为什么看不到类图? 什么是“overload(名复用)”啊? javamail中inputstream的长度问题 何处能下到 Tomcat?或其他简单易用的java server? 请教一个jbulider4的中文问题! 一个关于初始化的问题,很说明问题!请大家讨论一下! 请问这两个类应该怎么设计?需要更好的建议,谢谢!(参与有分)
static int CONCUR_READ_ONLY 该常量指示不可以更新的 ResultSet 对象的并发模式。
static int CONCUR_UPDATABLE 该常量指示可以更新的 ResultSet 对象的并发模式。
static int FETCH_FORWARD 该常量指示将按正向(即从第一个到最后一个)处理结果集中的行。
static int FETCH_REVERSE 该常量指示将按反向(即从最后一个到第一个)处理结果集中的行处理。
static int FETCH_UNKNOWN 该常量指示结果集中的行的处理顺序未知。
static int HOLD_CURSORS_OVER_COMMIT 该常量指示调用 Connection.commit 方法时不应关闭 ResultSet 对象。
static int TYPE_FORWARD_ONLY 该常量指示指针只能向前移动的 ResultSet 对象的类型。
static int TYPE_SCROLL_INSENSITIVE 该常量指示可滚动但通常不受其他的更改影响的 ResultSet 对象的类型。
static int TYPE_SCROLL_SENSITIVE 该常量指示可滚动并且通常受其他的更改影响的 ResultSet 对象的类型。
我在阎宏博士的《JAVA与模式》一书中看到了这样的说法,认为使用常量接口是错误的行为,建议读者不要使用,但没有说明原因,有明白个中缘由的高手解释一下吧,谢谢!
==================================》
For the date fields: (这一组是用来指定特定日期的常量字段) YEAR + MONTH + DAY_OF_MONTH
YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
YEAR + DAY_OF_YEAR
YEAR + DAY_OF_WEEK + WEEK_OF_YEAR
==================================》
For the time of day fields:(这一组是用来指定特定时间的常量字段) HOUR_OF_DAY
HOUR + MINUTE + SECOND
AM_PM + HOUR
==================================》
当设置年份时(Calendar.YEAR is 1),通常的做法是这样:Calendar calendar = Calendar.getInstance();
int expectedYearValue = 2006;
calendar.set(Calendar.YEAR, expectedYearValue);但是...你通常也可以这样
Calendar calendar = Calendar.getInstance();
int expectedYearValue = 2006;
calendar.set(Calendar.PM, expectedYearValue);由于Calendar.PM 和 Calendar.YEAR常量的值相同(都为整型 1),所以这里互换之后编译器不会发出任何警报,事实上你依然赋值了YEAR字段,但是阅读代码的人却看的莫名其妙,一头雾水,她或他不得不深入代码细节去看个究竟,这里更本就不该有PM常量的身影,她本来更本不该作为这个方法的参数而存在...----------
另一个麻烦在于硬编码,再比如上例的Calendar.set方法,她其中一个版本的完全申明如下:
set(field: int, value: int) : voidfield字段如上个问题中一样是代表需要赋值的字段是什么,第二个字段则是需要赋予的值
field字段本质上仅仅是一个int类型的变量(其他各种简单变量都可以,比如char, String, float...),所以你往往可以硬编码,比如我要赋值Year字段:int expectedYearValue = 2006;
calendar.set(1, expectedYearValue);这里编译器不会爆任何错误,然后我们再改动一下
calendar.set(999, expectedYearValue);编译器仍然认为是正确的,只有当进入运行时才会导致错误... ...编译器的强大功能被完全忽略和跳过了...这也可能会导致某种潜在的程序缺陷----
所以综上所述,直接使用int, char or String...这些简单类型作为常量使用是不太明智的(除非这些类型确实正好体现了他们需要代表常量的类型,比如 static final int MAX_INT_VALUE = 999;)。如果使用的是JDK1.5版本或以上,可以直接是使用Enum类型来代替这些东西,Enum的静态类型检查会大大有助于提高程序的可读性和健壮性;
如果很不幸的,你还必须使用JDK1.4或以下版本,比如我,可以参考《Effective Java》第5章21条,“用类来代替enum结构”,事实上JDK1.5中对Enum的模拟就是基于这种方式,只是将这种功能嵌入了语言特性中变成了语言的固有部分而已。@.@||~