在Java程序中,是不允许定义独立的函数和常量(当然,准确的说,只是被final修饰、只能赋值一次的变量)的。即使从它们本身的功能来看,完全不需要依附于什么东西,也要找个类或接口作为挂靠单位才行(在类里可以挂靠各种成员,而接口里则只能挂靠常量)。
挂靠的方法,是把它们加上static修饰符,定义为这个类或接口的静态成员。这方面的典型例子是java.lang.Math类——包含了大量的sin、cos这样的“函数”和PI、E这样的“常量”。
传统上,在访问这些挂靠了的函数、变量和常量的时候,需要在前面加上它们挂靠单位的名称。如果只是偶尔访问这些东西一下,这样的写法可以工作得很好;但是如果要频繁访问这些成员的话,这样的写法就显得比较罗嗦了。
精确的导入一个静态成员的方法,是在源文件的开头部分(任何类或接口的定义之前),加上类似这样的声明:
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机制,可以用一种更简单的方式,来访问类和接口的静态成员。不过,使用这一机制并不是没有代价的,在使用不当的时候可能给维护工作带来一定的困扰。因此,在具体使用之前,还要作一些两方面的权衡。
相关推荐
### Java Package与Import机制详解 #### 一、引言 对于很多刚开始接触Java编程的初学者来说,往往是从购买一本入门书籍开始他们的Java学习之旅。在这个过程中,他们可能会下载最新的Java SDK并安装在自己的电脑上...
### Java深度历险:Chapter 05 - package与import机制 #### 前言 Java是一种广泛使用的编程语言,尤其适合于开发企业级应用。在Java编程的过程中,理解和掌握`package`与`import`机制至关重要。这两者是Java类加载...
Java的包(package)和导入(import)机制是Java语言中用于组织和管理类文件的一种机制。包可以被理解为将相关的类和接口组织在一起的容器,它们的目的是为了更好的管理命名空间,避免类名之间的冲突,并提供访问...
在Java编程语言中,`package`和`import`是非常重要的两个概念,它们分别用于组织代码结构和引入外部类或包,对于理解Java程序的模块化和包管理机制至关重要。 ### Java中的Package #### 1. Package的概念 在Java中...
#### 一、Kotlin 包的理解与使用 在 Kotlin 中,**包**(Package)的概念与 Java 十分相似,它们都是用来组织和管理程序中的类、接口以及其他代码实体的重要工具。通过合理地使用包,可以有效地避免命名冲突、提高...
它是由Facebook AI Research (FAIR)开发的,旨在提供一个灵活、易于使用的平台,帮助研究人员和开发者监控和理解他们的模型在训练过程中的表现。这个“visdom服务static”文件与Visdom的静态资源有关,这些资源在...
`package` 和 `import` 关键字是Java语言提供的两种基本机制,用于帮助开发者更好地组织和管理代码。通过本篇文章,我们将深入探讨这两个关键字的作用和用法,并通过具体的例子来展示如何在实际的Java程序中使用它们...
### 反射机制详解 #### 一、反射机制概述 反射是Java的一项核心特性,它使得Java程序在运行时能够...深入理解这两个机制对于Java开发者来说至关重要,尤其对于那些从事框架开发和系统级编程的开发者而言更是如此。
为了在类之间进行交互,我们需要使用`import`关键字引入所需类。 - `import`语句位于类定义和包声明之后,但在任何方法定义之前。 2. **导入语法**: - 基本语法:`import package_name.class_name;` - 导入整个...
这是因为Java反射机制不仅是Java语言的一项重要特性,也是理解Java动态特性的关键所在。通过本文,我们将深入探讨Java反射机制的核心概念、基本原理及其应用场景。 #### 二、Java反射机制简介 Java反射机制允许...
在Java编程语言中,事件处理是图形用户界面(GUI)...理解这一机制对于开发具有用户友好界面的Java应用程序至关重要。通过实践"JavaEventDemo"这样的例子,新手可以更好地掌握事件处理的概念,并将其应用到实际项目中。
此外,`import static`语句用于导入静态成员,如常量和静态方法。 当我们谈论用Visual Studio .NET操控Java虚拟机时,这通常指的是使用跨平台开发工具,如MonoDevelop(现在是Visual Studio for Mac的一部分),...
3. **可维护性**:过度使用反射会使代码难以理解和维护,因为反射代码通常比较复杂且缺乏类型安全性。 总之,Java反射机制是一项强大的工具,它能够在运行时动态地获取和操作类的信息。然而,应该谨慎使用反射,...
### Java中的反射机制详解 反射,作为Java编程语言的核心特性之一,赋予了程序在运行时自我检查和修改其结构和行为的能力。...然而,正确理解和合理使用反射是至关重要的,以确保代码的效率、安全性和可维护性。
### Java六大核心机制详解 #### 一、克隆机制(Cloning Mechanism) **1.1 定义与原理** 克隆机制允许开发者在内存中快速复制对象,这...理解并熟练掌握这些机制对于提高开发效率和编写高质量的Java程序至关重要。