[J2SE 1.5]逐渐挖掘Static Import

原创 2004年08月27日 16:59:00

逐渐挖掘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”机制,借助这一机制,可以用略掉所在的类或接口名的方式,来使用静态成员。

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”
    }
}

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());
    }
}

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机制,可以用一种更简单的方式,来访问类和接口的静态成员。不过,使用这一机制并不是没有代价的,在使用不当的时候可能给维护工作带来一定的困扰。因此,在具体使用之前,还要作一些两方面的权衡。

参考资源

默认eclipse建立maven项目时,JDK版本往往是1.5

如果你用eclipse建立maven项目时,新建的项目往往JDK版本很低——1.5!怎么办?修改settings.xml文件,增加profile节点,如下所示: jdk-1.6 ...
  • zheng12tian
  • zheng12tian
  • 2014年10月30日 11:37
  • 2191

import static和import的区别及其使用规范

import static静态导入是JDK1.5中的新特性。一般我们导入一个类都用 import com.....ClassName;而静态导入是这样:importstatic com.....Cla...
  • riskys
  • riskys
  • 2017年02月12日 10:01
  • 449

J2SE 1.5的for增强循环

J2SE 1.5提供了另一种形式的for循环。借助这种形式的for循环,可以用更简单地方式来遍历数组和Collection等类型的对象。本文介绍使用这种循环的具体方式,说明如何自行定义能被这样遍历的类...
  • zhihang1103
  • zhihang1103
  • 2013年10月23日 23:03
  • 433

Maven项目build path的时候Libraries下 JRE版本是1.5,但我实际的JRE是1.7,为什么?

问题描述: 在构建maven WEB项目的时候,我的JDK是1.7 ,在Eclipse中也确认了版本是1.7 。 但是当我创建了一个Maven WEB项目的时候,在对这个项目进行build path...
  • weiguolong0306
  • weiguolong0306
  • 2015年11月24日 16:16
  • 2961

Java静态导入(import static)需谨慎

从Java 5 开始引入了静态导入语法(import static),其目是为了减少字符输入量,提高代码的可阅读性,以便更好地理解程序。我们先来看一个不使用静态导入的例子,也就是一般导入: publ...
  • softn
  • softn
  • 2016年05月31日 06:40
  • 390

1.5 J2SE学习中的30个基本概念

前言: 在我们学习Java的过程中,掌握其中的基本概念对我们的学习无论是J2SE,J2EE,J2ME都是很重要的,J2SE是Java的基础,所以有必要对其中的基本概念做以归纳,以便大家在以后的学习过程...
  • u010129251
  • u010129251
  • 2015年04月02日 11:25
  • 248

Android面试之J2SE基础

Android面试之J2SE基础
  • chun0801
  • chun0801
  • 2016年07月04日 21:11
  • 2280

JAVA编程思想(4) - 多态(一)

多态 在面向对象的程序设计语言中,多态是继数据抽象和继承之后的第三种基本类型。多态通过分离做什么和怎么做,从另一个角度将接口和实现分离开来。多态不但能够改善代码的组织结构和可读性,还能够创建可扩...
  • u011345136
  • u011345136
  • 2014年08月25日 23:06
  • 1117

静态导入import static的作用

最近学习Junit时,Assert类中的断言方法:assertEquals、assertTrue、assertFalse等等都是静态方法。例句中直接使用静态导入import static org.j...
  • shirley_paddy
  • shirley_paddy
  • 2017年07月19日 16:36
  • 152

J2EE和J2se的区别

不管是J2ee还是J2se,都是Java为不同用户提供的不同服务,也就是通过提供不同类型的类库满足不同用户的需求。 一、概述          j2se、j2ee和J2me是Java2平台的三个版本。...
  • YSC1123
  • YSC1123
  • 2015年01月10日 07:51
  • 7384
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[J2SE 1.5]逐渐挖掘Static Import
举报原因:
原因补充:

(最多只允许输入30个字)