静态导入(基础知识)

来源:互联网 发布:mt4缠论分型指标源码 编辑:程序博客网 时间:2024/05/24 05:02

我只是告诉您不要从类的实例调用类方法,除非您提供了类名。这样做,使得类方法在何处定义显得比较模糊。这同样也适用于对类变量的访问(不包括类常量)。

Java甚至允许您将事情变得更容易混淆。在类中使用静态导入,可以让您使用其它类中定义的类方法和类变量,而且这些类方法和类变量就像在本地定义的一样。换句话说,静态导入允许您在调用其它类中定义的静态成员时,可以忽略类名。

这里有一些关于静态导入正确的和错误的用法。首先,我演示一个错误的用法。修改CourseSessionTest:



// avoid doing this

package sis.studentinfo;



import junit.framework.TestCase;

import java.util.*;

import static sis.studentinfo.DateUtil.*; // poor use of static import



public class CourseSessionTest extends TestCase {

   private CourseSession session;

   private Date startDate;



   public void setUp() {

      startDate = createDate(2003, 1, 6); // poor use of static import

      session = CourseSession.create("ENGL", "101", startDate);

   }

   ...

   public void testCourseDates() {

      // poor use of static import:

      Date sixteenWeeksOut = createDate(2003, 4, 25);

      assertEquals(sixteenWeeksOut, session.getEndDate());

   }

   ...

}



静态导入语句看起来和普通的import语句非常相似。但是,普通import语句从某个包中导入了一个或所有的类,而静态import语句从某个类中导入一个或所有的类方法以及类变量。上面的例子,从类DateUtil中导入了所有的类方法和类变量。由于DateUtil中只有一个类方法,所以您可以显式地导入:



import static sis.studentinfo.DateUtil.createDate;

如果DateUtil包含了多个名字为createDate的类方法(但是有不同的参数),或者只是包含了一个名字叫createDate的类变量,那么它们都会被静态导入。

静态导入使您不用提供类名,这样做可以偷点儿懒,但也引入了不必要的混淆。正如createDate在何处定义这个问题。如果您正在编写的某个类,需要调用多个外部类方法(可能几十个甚至更多),这样您或许有了使用静态导入的借口。但是,更好的方法是,弄明白为什么需要这么多的静态调用,或许您需要重新审视类的设计。

使用静态导入的可能理由之一是:简化对多个类常量的调用,而且这些类常量定义在一个地方。假设您创建了多个报表类,而且每个报表类都需要将换行符追加到输出,所以每个报表类都需要用到常量NEWLINE,就像RosterReporter中的定义:

static final String NEWLINE = System.getProperty("line.separator");

您不会希望在每个报表类中都重复定义这个常量。所以您可以创建一个新类,这个类的职责就是为了持有常量。稍后,它也可以持有别的常量,例如对任何报表类都适用的页面宽度。

package sis.report;



public class ReportConstant {

   public static final String NEWLINE =

      System.getProperty("line.separator");

}

在典型的报表类中,由于很多地方都需要使用常量NEWLINE,所以您可以增加一个静态导入,这样可以使您的代码看起来干净一些[3]:

package sis.report;



import junit.framework.TestCase;

import sis.studentinfo.*;

import static sis.report.ReportConstant.NEWLINE;



public class RosterReporterTest extends TestCase {

   public void testRosterReport() {

      CourseSession session =

         CourseSession.create(

            "ENGL", "101", DateUtil.createDate(2003, 1, 6));



      session.enroll(new Student("A"));

      session.enroll(new Student("B"));



      String rosterReport = new RosterReporter(session).getReport();

      assertEquals(

         RosterReporter.ROSTER_REPORT_HEADER +

         "A" + NEWLINE +

         "B" + NEWLINE +

         RosterReporter.ROSTER_REPORT_FOOTER + "2" +

         NEWLINE, rosterReport);

   }

}

您可以针对类RosterReporter进行类似的改动。

将一组常量放到一个没有行为(方法)的类中,这是一种受到置疑的面向对象设计。类不可以存在于真空。最好取消类ReportConstants中的常量,将这些常量作为其它普通Java类的一部分,例如类Report。

关于静态导入,还有一些需要注意的:

●          针对一个给定的包,不可能用一行语句静态地导入所有类的所有类方法和类变量。也就是说,您不能这样编写代码:

     import static java.lang.*;  // this does not compile!

●          如果一个本地方法,和一个静态导入的方法有着相同的名字,那么本地方法被调用。

谨慎地使用静态导入。因为静态导入使得类方法和类变量的定义位置变得模糊,所以加大了理解代码的难度。使用静态导入的原则是:限制静态导入的使用,不要在应用程序中普遍使用静态导入。