Static Import


I just told you to not call class methods from the instance side unless you supply the class name. Doing so obscures where the class method is defined. The same applies for accessing class variables (not including class constants).

Java permits you to muddle things even further. Including a static import in a class allows you to use class methods or variables defined in a different class as if they were defined locally. In other words, a static import allows you to omit the class name when referring to static members defined in another class.

There are appropriate uses for static import and inappropriate uses. I'll demonstrate an inappropriate use first. Modify 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());    }    ... } 

A static import statement looks similar to a regular import statement. However, a regular import statement imports one or all classes from a package, while a static import statement imports one or all class members (variables or methods) from a class. The above example imports all class members from the class DateUtil. Since there is only one class method in DateUtil, you could have explicitly imported just that method:

 import static sis.studentinfo.DateUtil.createDate; 

If DateUtil were to contain more than one class method with the name createDate (but with different argument lists), or if it also were to contain a class variable named createDate, they would each be statically imported.

Statically importing methods to avoid having to provide a class name in a few spots is lazy and introduces unnecessary confusion. Just where is createDate defined? If you are coding a class that requires quite a few external class method calls (perhaps a couple dozen or more), you might have an excuse to use static import. But a better approach would be to question why you need to make so many static calls in the first place and perhaps revisit the design of the other class.

A similar, potentially legitimate use of static import is to simplify the use of several related class constants that are gathered in a single place. Suppose you've created several report classes. Each report class will need to append new line characters to the output, so each report class will need a NEWLINE constant such as the one currently defined in RosterReporter:

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

You don't want the duplication of defining this constant in each and every report class. You might create a new class solely for the purpose of holding this constant. Later it might hold other constants such as the page width for any report.

 package sis.report; public class ReportConstant {    public static final String NEWLINE =       System.getProperty("line.separator"); } 

Since the NEWLINE constant will be used in a lot of places in a typical report class, you can add a static import to clean up your code a little:[3]

[3] You can eliminate the need for the NEWLINE constant entirely in a few other ways. You'll learn about one such technique, using the Java Formatter class, in Lesson 8.

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

You can make similar changes to the RosterReporter class.

Putting a bunch of constants in a class with no behavior (methods) represents questionable OO design. Classes don't exist in a vacuum; the constants in ReportConstants class may be better off as part of another "normal" Java class, such as a class named Report.

Additional notes on static import:

  • It is not possible to statically import all members from all classes in a given package in a single statement. That is, you cannot code:

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

  • If a local method has the same signature as a statically imported method, the local method is called.

Use static imports with prudence. They make it more difficult to understand your classes by obscuring where members are defined. The rule of thumb is to limit use of static imports to things that are both universal and pervasive in your application.



Agile Java. Crafting Code with Test-Driven Development
Agile Javaв„ў: Crafting Code with Test-Driven Development
ISBN: 0131482394
EAN: 2147483647
Year: 2003
Pages: 391
Authors: Jeff Langr

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net