王朝网络
分享
 
 
 

[J2SE 1.5]逐渐挖掘Static Import

王朝java/jsp·作者佚名  2006-01-09
宽屏版  字体: |||超大  

.article {padding:1em;background:white;}

.abstract {padding:1em 1ex 1em 2em;}

.author, .date {padding:0.5ex 0 0 0;}

h1.title, h2.major, h3.minor, h3.listing {

margin:1ex 2px 1ex;color:#0066CC;font-family:sans-serif;

}

h1.title {margin-left:0;} h3.listing {margin:1ex 2px 0;}

h4.label {

margin:0 -1ex 1ex;padding:4px;border:1px solid #0066CC;

color:white;background:#0066CC;

}

div.sidebar {

margin:1.5em 0.5ex 1em;padding:0 1ex;

border:2px solid #0066CC;-moz-border-radius:8px;

}

h4.label:first-child {

-moz-border-radius-topleft:4px;-moz-border-radius-topright:4px;}

.code {

margin:0 0 1ex;padding:1em;background:#CCCCCC;font:monospace;

border:1px solid #CCCCCC;-moz-border-radius:8px;

}

.subtitle {font-size:80%;padding-left:1ex;}

dt {font-weight:bold;} li {margin-top:1ex;margin-bottom:1ex;}

p {margin:1em 0;} .article a {text-decoration:underline;}

.article a:link {color:#0000FF;} .article a:visited {color:#6699FF;}

.article a:hover {color:#FF0000;background:#FFFF99;}

逐渐挖掘Static Import

更简单的访问静态成员

孙海涛 (sun.haitao@126.com)

2004年8月27日

J2SE 1.5里引入了“Static Import”机制,借助这一机制,可以用略掉所在的类或接口名的方式,来使用静态成员。本文介绍这一机制的使用方法,以及使用过程中的注意事项。

在Java程序中,是不允许定义独立的函数和常量(当然,准确的说,只是被final修饰、只能赋值一次的变量)的。即使从它们本身的功能来看,完全不需要依附于什么东西,也要找个类或接口作为挂靠单位才行(在类里可以挂靠各种成员,而接口里则只能挂靠常量)。

挂靠的方法,是把它们加上static修饰符,定义为这个类或接口的静态成员。这方面的典型例子是java.lang.Math类——包含了大量的sin、cos这样的“函数”和PI、E这样的“常量”。

传统上,在访问这些挂靠了的函数、变量和常量的时候,需要在前面加上它们挂靠单位的名称。如果只是偶尔访问这些东西一下,这样的写法可以工作得很好;但是如果要频繁访问这些成员的话,这样的写法就显得比较罗嗦了。

J2SE 1.5里引入了“Static Import”机制,借助这一机制,可以用略掉所在的类或接口名的方式,来使用静态成员。

“静态导入”或者“静态成员导入”

Static Import机制常常被直译成“静态导入”。但是从含义上看,“静态成员导入”是更为贴切的译法。不过考虑到“静态导入”这说法比较简短,估计还是会有强大的生命力。

只包括常量定义的接口

有一种省去常量前的挂靠单位的变通做法:将所有的常量都定义到一个接口里面,然后让需要这些常量的类实现这个接口(这样的接口有一个专门的名目,叫作“Constant Interface”)。

这个方法可以工作。但是,因为这样一来,就可以从“一个类实现了哪个接口”推断出“这个类需要使用哪些常量”,有“会暴露实现细节”的问题。

1.精确导入的方式

精确的导入一个静态成员的方法,是在源文件的开头部分(任何类或接口的定义之前),加上类似这样的声明:

import static 包名.类或接口名.静态成员名;

注意尽管这个机制的名目是叫做“Static Import”,但是在这里的次序却是正好相反的“import static”。

一经导入之后,在整个源文件的范围内,就可以直接用这个成员的名字来访问它了。

清单1:用精确导入的方式,导入sin和PI

//精确的导入Math.sin和Math.PI

import static java.lang.Math.sin;

import static java.lang.Math.PI;

public class StaticImportSampleA {

public static void main(String[] args) {

System.out.println(sin(PI/2));//输出“1.0”

}

}

游离于包外的类和接口们的特别问题

Java语言并未要求每个类和接口都必须属于某一个包。但是,在J2SE 1.4以后,无论是import语句也好,还是import static语句也好,都要求给一个所在包名出来。换而言之,对于不属于任何包的类和接口,是既不能用import导入它本身,也不能用import static导入它的静态成员的。

2.按需导入的方式

Static Import机制也支持一种不必逐一指出静态成员名称的导入方式。这时,要采用这样的语法:

import static 包名.类或接口名.*;

注意这种方式只是指出遇到来历不明的成员时,可以到这个类或接口里来查找,并不是把这个类或接口里的所有静态成员全部导入。

清单2:用按需导入的方式,导入sin和PI

//声明遇到来历不明的成员时到java.lang.Math中去寻找

import static java.lang.Math.*;

public class StaticImportSampleB {

public static void main(String[] args) {

System.out.println(sin(PI/2));//输出“1.0”

}

}

3.可以导入的种种东西

使用import static语句,可以导入一个类里的一切被static修饰的东西,包括变量、常量、方法和内类。

清单3:变量、常量、方法和内类都可以导入

package com.example.p3;

public class StaticImportee {

public static int one = 1;

public static final int TWO = 2;

public static int three() {

return 3;

}

public static class Four {

public int value() {

return 4;

}

}

}

package com.example.p3;

import static com.example.p3.StaticImportee.*;

public class StaticImporter {

public static void main(String[] args) {

System.out.println(one);

System.out.println(TWO);

System.out.println(three());

System.out.println(new Four());

}

}

不受影响的访问控制

Static Import不能突破Java语言中原有的访问控制机制的限制,不过也并不在这方面增加新的约束。原来有权限访问的静态成员,都可以被导入和使用;而原来无权限访问的静态成员,用了这个方法之后也仍然是访问不能。

4.导入之间的冲突问题

不同的类(接口)可以包括名称相同的静态成员。因此,在进行Static Import的时候,可能会出现“两个语句导入同名的静态成员”的情况。

在这种时候,J2SE 1.5会这样来加以处理:

如果两个语句都是精确导入的形式,或者都是按需导入的形式,那么会造成编译错误。

如果一个语句采用精确导入的形式,一个采用按需导入的形式,那么采用精确导入的形式的一个有效。

注意,如果两个同名的静态成员一个是属性,而另一个是方法,那么因为使用时的写法有差异,不会造成任何的冲突。

清单4:采用精确导入的形式的一个有效

package com.example.p4;

import static com.example.p4.Importee1.name;

import static com.example.p4.Importee1.*;

import static com.example.p4.Importee2.*;

import static com.example.p4.Importee2.pass;

public class Importer {

public static void main(String[] args) {

System.out.println(name);//输出“Name1”

System.out.println(pass);//输出“Pass2”

}

}

package com.example.p4;

public class Importee1 {

public static String name = "Name1";

public static String pass = "Pass1";

}

package com.example.p4;

public class Importee2 {

public static String name = "Name2";

public static String pass = "Pass2";

}

5.本地和外来的竞争

有时候,导入的东西还可能和本地的东西相冲突,这种情况下的处理规则,是“本地优先”。

清单5:本地的优先于外来的

package com.example.p5;

import static com.example.Zero.*;

public class One {

public static int flag = 1;

public static void main(String[] args) {

System.out.println(flag);//输出“1”

}

}

package com.example.p5;

public class Zero {

public static int flag = 0;

}

6.Static Import的负面影响

在编译期间,所有因Static Import的存在而简化了的名字,都会被编译器打回原型。因此在性能方面,Static Import没有任何影响。但是名字简化却可能造成一些维护方面的问题。

去掉静态成员前面的类型名,固然有助于在频繁调用时显得简洁,但是同时也失去了关于“这个东西在哪里定义”的提示信息,增加了阅读理解的麻烦。如果导入的来源很著名(比如java.lang.Math),或者来源的总数比较少,这个问题并不严重;但是在不属于这两种的情况下,这就不是基本可以忽略的问题了。

7.归纳总结

借助J2SE 1.5里提供的Static Import机制,可以用一种更简单的方式,来访问类和接口的静态成员。不过,使用这一机制并不是没有代价的,在使用不当的时候可能给维护工作带来一定的困扰。因此,在具体使用之前,还要作一些两方面的权衡。

参考资源

可以通过Sun的Java Technology页面找到下载J2SE 1.5的SDK及其文档的链接,目前最新的版本是J2SDK 1.5 Beta 2。注意在使用这一版本的javac的时候,要加上“-source 1.5”作为参数,才能编译使用了J2SE 1.5中新增语言特性的源代码。

John Zukowski在《驯服 Tiger:Tiger 预览版现已推出》一文中,介绍了如何开始使用J2SDK 1.5的基础知识。不过因为这篇文章是依照J2SDK 1.5 Alpha版的状况所写,所以里面提到的一些细节(如下载地址和默认安装路径)已经发生了变化。

JSR 201: Extending the Java Programming Language with Enumerations, Autoboxing, Enhanced for loops and Static Import》定义了很多J2SE 1.5中的新语言特性,包括了“Static Import”。

Joshua Bloch在《Effective Java》一书的第四章《Classes and Interfaces》中,解释了只包括常量的接口所存在的问题。

Calvin Austin在《J2SE 1.5 in a Nutshell》一文中,对J2SE 1.5中的各种新特性,进行了全面而概括的介绍。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
 
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有