1. Trang chủ
  2. » Công Nghệ Thông Tin

Beginning Java SE 6 Platform From Novice to Professional phần 2 ppsx

51 366 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 51
Dung lượng 364,59 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

After compiling the source code and running this application, you’ll discover the following output, which reveals that Dialog 1 is not a true ownerless window:ALL WINDOWS frame0: class j

Trang 1

// Create a true ownerless Swing dialog.

JDialog d2 = new JDialog ((Window) null, "Dialog 2");

d2.setName ("Dialog 2");

// Create an ownerless frame

Frame f = new Frame ();

f.setName ("Frame 1");

// Create a window owned by the frame

Window w1 = new Window (f);

w1.setName ("Window 1");

// Create an ownerless window

Window w2 = new Window (null);

w2.setName ("Window 2");

// Output lists of all windows, ownerless windows, and frame windows.System.out.println ("ALL WINDOWS");

Window [] windows = Window.getWindows ();

for (Window window: windows)System.out.println (window.getName ()+": "+window.getClass ());System.out.println ();

System.out.println ("OWNERLESS WINDOWS");

Window [] ownerlessWindows = Window.getOwnerlessWindows ();

for (Window window: ownerlessWindows)System.out.println (window.getName ()+": "+window.getClass ());System.out.println ();

System.out.println ("FRAME WINDOWS");

Frame [] frames = Frame.getFrames ();

for (Frame frame: frames)System.out.println (frame.getName ()+": "+frame.getClass ());}

}

Trang 2

After compiling the source code and running this application, you’ll discover the following output, which reveals that Dialog 1 is not a true ownerless window:

ALL WINDOWS

frame0: class javax.swing.SwingUtilities$SharedOwnerFrame

Dialog 1: class javax.swing.JDialog

Dialog 2: class javax.swing.JDialog

Frame 1: class java.awt.Frame

Window 1: class java.awt.Window

Window 2: class java.awt.Window

OWNERLESS WINDOWS

frame0: class javax.swing.SwingUtilities$SharedOwnerFrame

Dialog 2: class javax.swing.JDialog

Frame 1: class java.awt.Frame

Window 2: class java.awt.Window

FRAME WINDOWS

frame0: class javax.swing.SwingUtilities$SharedOwnerFrame

Frame 1: class java.awt.Frame

Navigable Sets

Chapter 2 introduces Java SE 6’s enhanced collections framework One enhancement

worth mentioning here is a new java.util.NavigableSet<E>interface, which extends the

older java.util.SortedSet<E>interface and facilitates navigating through an ordered

set-based collection

A navigable set can be accessed and traversed in ascending order via the Iterator<E>

iterator()method, and in descending order via the Iterator<E> descendingIterator()

method It can return the closest matches for given search targets via methods public E

ceiling(E e), public E floor(E e), public E higher(E e), and public E lower(E e) By

default, these closest-match methods find the closest match in ascending order To find

a closest match in descending order, first obtain a reverse-order view of the set via the

NavigableSet<E> descendingSet()method Listing 1-6 presents an application that

demonstrates descendingSet()and the four closest-match methods, with comments

that describe each closest-match method in detail

Trang 3

static NavigableSet<String> citiesSet;

public static void main (String [] args){

String [] cities ={

// Create and populate a navigable set of cities

citiesSet = new TreeSet<String> ();

for (String city: cities)citiesSet.add (city);

// Dump the city names in ascending order Behind the scenes, the// following code is implemented in terms of

//

// Iterator iter = citiesSet.iterator ();

// while (iter.hasNext ())// System.out.println (iter.next ());

System.out.println ("CITIES IN ASCENDING ORDER");

for (String city: citiesSet)System.out.println (" "+city);

System.out.println ();

// Dump the city names in descending order Behind the scenes, the// following code is implemented in terms of

Trang 4

// Iterator iter = citiesSet.descendingSet.iterator ();

// while (iter.hasNext ())// System.out.println (iter.next ());

System.out.println ("CITIES IN DESCENDING ORDER");

for (String city: citiesSet.descendingSet ())

System.out.println (" "+city);

System.out.println ();

// Demonstrate the closest-match methods in ascending order set

System.out.println ("CLOSEST-MATCH METHODS/ASCENDING ORDER DEMO");

// ceiling() returns the least element in the set greater than or equal// to the given element (or null if the element does not exist)

System.out.println (" ceiling('"+city+"'): "+citiesSet.ceiling (city));

Trang 5

// floor() returns the greatest element in the set less than or equal to// the given element (or null if the element does not exist).

System.out.println (" floor('"+city+"'): "+citiesSet.floor (city));

// higher() returns the least element in the set strictly greater than// the given element (or null if the element does not exist)

System.out.println (" higher('"+city+"'): "+citiesSet.higher (city));

// lower() returns the greatest element in the set strictly less than // the given element (or null if the element does not exist)

System.out.println (" lower('"+city+"'): "+citiesSet.lower (city));

}}

As shown in the source code, the closest-match methods return set elements thatsatisfy various conditions For example, lower()returns the element that is greater thanall other set elements, except for the element described by lower()’s argument; themethod returns null if there is no such element Although this description is intuitivewhen you consider a set that is ordered in ascending order, intuition fails somewhatwhen you consider the set ordered in descending order For example, in the followingoutput, Belgrade is lower than Berlin in ascending order, and Buenos Aires is lower thanBerlin in descending order:

CITIES IN ASCENDING ORDER

BaghdadBangkokBeijingBelgradeBerlinBuenos Aires

Trang 6

CITIES IN DESCENDING ORDER

Buenos AiresBerlinBelgradeBeijingBangkokBaghdadCLOSEST-MATCH METHODS/ASCENDING ORDER DEMO

ceiling('Berlin'): Berlinfloor('Berlin'): Berlinhigher('Berlin'): Buenos Aireslower('Berlin'): Belgrade

ceiling('C'): nullfloor('C'): Buenos Aireshigher('C'): nulllower('C'): Buenos Airesceiling('A'): Baghdadfloor('A'): nullhigher('A'): Baghdadlower('A'): nullCLOSEST-MATCH METHODS/DESCENDING ORDER DEMO

ceiling('Berlin'): Berlinfloor('Berlin'): Berlinhigher('Berlin'): Belgradelower('Berlin'): Buenos Aires

ceiling('C'): Buenos Airesfloor('C'): null

higher('C'): Buenos Aireslower('C'): null

ceiling('A'): nullfloor('A'): Baghdadhigher('A'): nulllower('A'): Baghdad

Trang 7

Note Here are a few other interesting changes in Java SE 6:

• Java SE 6 changes the class file version number to 50.0 because it supports split verification (see Appendix B)

• Java SE 6’s jarsigner,keytool, and kinitsecurity tools no longer echo passwords to thescreen

• The javax.swing.text.Segmentclass, which allows fast access to a segment of text, nowimplements the CharSequenceinterface You can use Segmentin regular-expression contexts,for example

Java SE 6, Update 1 and Update 2

Following the initial release of Java SE 6 (which is the focus of this book), Sun released its first Java SE 6 update to introduce a number of bug fixes This update release specifies

6u01 as its external version number, and 1.6.0_01-b06 (where b stands for build) as its

internal version number

One bug that has been fixed in 6u01 concerns memory leak problems with severalmethods For example, the Threadclass specifies a public static Map<Thread,

StackTraceElement[]> getAllStackTraces()method that returns a map of stack traces for all live threads Also, the java.lang.management.ThreadMXBeaninterface specifies severalgetThreadInfo()methods that return thread information According to Bug 6434648

“Native memory leak when use Thread.getAllStackTraces(),” all of these methods have amemory leak that leads to an OutOfMemoryError You can reproduce this problem, which hasbeen solved in this update release, by running the following application (which might runfor a considerable period of time before OutOfMemoryErroris thrown) on the initial release

Thread.getAllStackTraces();

}}}

Trang 8

Another bug that has been fixed in 6u01 is Bug 6481004 “SplashScreen.getSplashScreen()fails in Web Start context.” According to this bug, migrating a stand-alone application

that uses the Splash Screen API to Java Web Start results in a java.security

AccessControlExceptionbeing thrown This exception is thrown as a result of the

System.loadLibrary("splashscreen")method call in the public static synchronized

SplashScreen getSplashScreen()method not being placed inside a doPrivileged()block

The Java SE 6 Update Release Notes page (http://java.sun.com/javase/6/webnotes/

ReleaseNotes.html) provides a complete list of all the bugs that have disappeared in

the 6u01 update

While this chapter was being written, a second Java SE 6 update was released

Although this update was rumored to contain a slimmed-down JRE, as pointed out

by the posting on TheServerSide.com titled “Rumor: Java 6 update 2 will be 2-4MB?”

(http://www.theserverside.com/news/thread.tss?thread_id=45377), the second update

offered nothing quite so dramatic This rumor was most likely based on the

much-discussed Consumer JRE, which Chet Haase discusses in his “Consumer JRE: Leaner,

Meaner Java Technology” article (http://java.sun.com/developer/technicalArticles/

javase/consumerjre/)

To see what the second update has to offer, check out Sun’s Java SE 6 Update ReleaseNotes page

Summary

Java SE 6 (formerly known as Mustang) officially arrived on December 11, 2006 This

release contains many new and improved features that will benefit Java developers for

JSR 221 JDBC 4.0 API Specification, JSR 222 Java Architecture for XML Binding (JAXB) 2.0,

JSR 223 Scripting for the Java Platform, JSR 224 Java API for XML-Based Web Services

(JAX-WS) 2.0, JSR 268 Java Smart Card I/O API, and JSR 269 Pluggable Annotation

Pro-cessing API Although not identified by JSR 270, JSR 173 Streaming API for XML, JSR 181

Web Services Metadata for the Java Platform, and JSR 250 Common Annotations for the

Java Platform are also component JSRs

Java SE 6 provides many features that set it apart from its predecessors Some ofthese features were explored in this chapter, and include a trio of new action keys and a

method to hide/show action text, the ability to clear a button group’s selection, reflection

Trang 9

enhancements, the GroupLayout layout manager, an Image I/O GIF writer plug-in, incremental improvements to the Stringclass, LCD text support, new NumberFormatmethods for working with rounding modes, an improved Fileclass infrastructure, window icon images, the ability to specify a minimum window size, an interruptible I/O switch for Solaris, DeflatorInputStreamand InflatorOutputStreamclasses added to the java.util.zippackage, ownerless windows, and navigable sets.

Following the initial release of Java SE 6 (which is the focus of this book), Sunreleased a pair of updates that primarily fix bugs

Test Your Understanding

How well do you understand Java SE 6 thus far? Test your understanding by answeringthe following questions and performing the following exercises (The answers are presented in Appendix D.)

1. Why does Sun refer to Java SE 6 instead of J2SE 6.0?

2. Identify the themes of Java SE 6

3. Does Java SE 6 include internationalized resource identifiers (IRIs)?

4. What is the purpose of Action’s new DISPLAYED_MNEMONIC_INDEX_KEYconstant?

5. Why should you create a Swing program’s GUI only on the event-dispatchingthread?

6. How do you establish a window’s minimum size?

7. Describe each of NavigableSet<E>’s closest-match methods

8. Does public JDialog(Frame owner)create a true ownerless window when owner

is null?

Trang 10

Core Libraries

Java’s core libraries support mathematics, input/output (I/O), collections, and more

Java SE 6 updates existing core libraries and integrates new libraries into the core This

chapter explores the following core library topics:

• BitSetenhancements

• Compiler API

• I/O enhancements

• Mathematics enhancements

• New and improved collections

• New and improved concurrency

• Extension mechanism and ServiceLoader API

BitSet Enhancements

The java.util.BitSetclass implements a growable vector of bits Because of its

compact-ness and other advantages, this data structure is often used to implement an operating

system’s priority queues and facilitate memory page allocation Unix-oriented file

sys-tems also use bitsets to facilitate the allocation of inodes (information nodes) and disk

sectors And bitsets are useful in Huffman coding, a data-compression algorithm for

achieving lossless data compression

C H A P T E R 2

Trang 11

Although no new features have been added to BitSet, Java SE 6 has improved thisclass in the following ways:

• According to Bug 4963875 “Reduction of space used by instances of java.util.BitSet,”the clone()method now returns a clone that can be smaller than the original bitset;bs.size() == bs.clone().size()is no longer guaranteed to be true Also, a serializedbitset can be smaller These optimizations reduce wasted space However, a cloned

or serialized bitset is not trimmed if the bitset was created via BitSet(int nbits), andits implementation size has not changed since creation

• The equals(Object obj)method is now speed-optimized for sparse bitsets (only afew bits are set) It returns false when the number of words in the logical lengths

of the bitsets being compared differ Please consult Bug 4979017

“java.util.BitSet.equals(Object) can be optimized” for more information

• The hashCode()method has been speed-optimized to hash only the used part of abitset (the bitset’s logical length), as opposed to the entire bitset (its implementa-tion size) You can find more information about this optimization by reading Bug

4979028 “BitSet.hashCode() unnecessarily slow due to extra scanning of zero bits.”

• The toString()method has been speed-optimized for large sparse bitsets Checkout Bug 4979031 “BitSet.toString() is too slow on sparse large bitsets” for moreinformation

• Some of BitSet’s methods now call various methods in the Longclass instead ofimplementing equivalent methods For example, the BitSetclass’s public intnextSetBit(int fromIndex)method invokes the Longclass’s public static int numberOfTrailingZeroes(long i)method This results in a simpler, faster, andsmaller BitSetimplementation Bug 5030267 “Use new static methods Long.highestOneBit/Long.bitCount in java.util.BitSet” provides more information Also, you might want to check out the BitSet.javasource file

• Previous violations of BitSet’s internal invariants are no longer tolerated Forexample, given bs.set(64,64);, bs.length()now returns 0 (instead of 64) andisEmpty()returns true (instead of false) More information can be found by reviewing Bug 6222207 “BitSet internal invariants may be violated.”

Compiler API

The ability to dynamically compile Java source code is needed in many situations Forexample, the first time a web browser requests a JavaServer Pages (JSP)-based document,the JSP container generates a servlet and compiles the servlet’s code

Trang 12

Prior to Java 1.2, you could achieve dynamic compilation only by creating a rary javafile and invoking javacvia Runtime.exec() Alternatively, you could access

tempo-javacinternals The first approach was problematic because of platform-specific process

behavior and applet security restrictions The latter approach suffered from being

undoc-umented and compiler-specific

Java 1.2 let you programmatically access the compiler via the JDK’s tools.jarfile

This access remained undocumented until Java 5 debuted The following static methods

in tools.jar’s com.sun.tools.javac.Mainclass let you access the compiler:

• public static int compile(String[] args)

• public static int compile(String[] args, PrintWriter out)The argsparameter identifies the command-line arguments normally passed tojavac The outparameter specifies the location of compiler diagnostic output (error

and warning messages) Each method returns the same value as javac’s exit code

As useful as these methods are, they are limited in the way they interact with theirenvironment For starters, they input source code from files and output compiled code

to files Also, they report errors to a single output stream—no mechanism exists to return

diagnostics as structured data I refer you to JSR 199 (http://jcp.org/en/jsr/

detail?id=199) for more information

To address this limitation, Sun has integrated the Compiler API into Java SE 6’s corelibraries This API offers the following:

• Programmatic access to the compiler

• Ability to override the manner in which the compiler reads and writes source andclass files

• Access to structured diagnostic information

Access to the Compiler and Other Tools

The Compiler API is hosted by the javax.toolspackage, which is designed to let

programs invoke various tools, beginning with compilers This package consists of six

classes, eleven interfaces, and three enumerations The entry point into javax.toolsis

the ToolProviderclass, from which you can access the default Java compiler:

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

The getSystemJavaCompiler()method returns an object that represents the defaultJava compiler If a compiler is not available (tools.jarmust be in the classpath), this

method returns null

Trang 13

The returned object is created from a class that implements the JavaCompilerinterface Using this interface, you can do the following:

• Identify the source versions of the Java language that are supported by the compiler

• Determine if a compiler option is supported

• Run the compiler with specific I/O streams and arguments

• Obtain the standard file manager

• Create a future (a java.util.concurrent.Futureobject that stores the result of

an asynchronous computation) for a compilation task

Identifying the Java language source versions that are supported by the compiler isimportant because a Java compiler cannot compile future source code that includes newlanguage features and new/enhanced APIs To determine the supported versions, call theJavaCompilerinterface’s inherited Set<SourceVersion> getSourceVersions()method Thismethod returns a java.util.Set<E>of SourceVersionenumeration constants whose methods provide the desired information

Certain compiler options (such as -g, to generate all debugging information) can bespecified when programmatically running the compiler Before specifying an option, you must determine if the option is supported Accomplish this task by calling the JavaCompilerinterface’s inherited int isSupportedOption(String option)method If theoption is not supported, this method returns -1; the number of required arguments for the option is returned if the option is supported Listing 2-1 demonstrates

isSupportedOption()and getSourceVersions()

Trang 14

if (args.length != 1){

System.err.println ("usage: java CompilerInfo option");

return;

}

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler ();

if (compiler == null){

System.err.println ("compiler not available");

return;

}

System.out.println ("Supported source versions:");

Set<SourceVersion> srcVer = compiler.getSourceVersions ();

for (SourceVersion sv: srcVer)System.out.println (" " + sv.name ());

int nargs = compiler.isSupportedOption (args [0]);

if (nargs == -1)System.out.println ("Option "+args [0]+" is not supported");

elseSystem.out.println ("Option "+args [0]+" takes "+nargs+

" arguments");

}}

After compiling CompilerInfo.java(javac CompilerInfo.java), run the applicationwith -gas the single command-line argument (as in java -g CompilerInfo) In response,

you should observe the following output:

Supported source versions:

RELEASE_3RELEASE_4RELEASE_5RELEASE_6Option -g takes 0 arguments

Trang 15

The simplest way to run the compiler is to invoke the JavaCompilerinterface’s ited int run(InputStream in, OutputStream out, OutputStream err, String arguments)method This method lets you specify the input, output, and error I/O streams (nullarguments refer to System.in, System.out, and System.err), and a variable list of Stringarguments to pass to the compiler This method returns zero on success and a nonzerovalue on failure If any of the elements in the arguments array are null references, thismethod throws a NullPointerException Listing 2-2 demonstrates the run()method.

System.err.println ("usage: java CompileFiles1 srcFile [srcFile]+");return;

}JavaCompiler compiler = ToolProvider.getSystemJavaCompiler ();

if (compiler == null){

System.err.println ("compiler not available");

return;

}

compiler.run (null, null, null, args);

}}

When you execute CompileFiles1, you can specify filename and compiler optionarguments in any order For example, java CompileFiles1 -g x.java y.javacompilesx.javaand y.java Furthermore, all debugging information is generated and stored ineach resulting class file

Although the run()method is easy to use, there is not much you can do in the way

of customization For example, you cannot specify a listener that is invoked with nostic information when a problem is discovered in the source code For more advanced

Trang 16

diag-customization, you need to work with the standard (or some other) file manager, and a

future for a compilation task

The Standard File Manager

The compiler tool is associated with the standard file manager, which is responsible for

creating file objects—objects whose classes implement the JavaFileObjectinterface

These file objects represent regular files, entries in ZIP files, or entries in other kinds of

containers Invoke the following method of JavaCompilerto obtain the standard file

• localeidentifies the locale in which diagnostic messages are formatted nullindicates the default locale

• charsetidentifies the character set for decoding bytes nullindicates the platform’sdefault character set

Continuing from this section’s earlier example, the following example retrieves thecompiler’s standard file manager, choosing the default diagnostic listener, locale, and

character set:

StandardJavaFileManager sjfm;

sjfm = compiler.getStandardFileManager (null, null, null);

Compilation Task Futures

After obtaining the standard file manager, you can invoke one of various

StandardJavaFileManagermethods to retrieve an Iterableof JavaFileObjects Each

JavaFileObjectabstracts one file, which might or might not be a regular file For

example, assuming that argsis an array of command-line arguments, the following

example creates a JavaFileObjectfor each argument and returns these objects via an

Iterable:

Trang 17

Iterable<? extends JavaFileObject> fileObjects;

fileObjects = sjfm.getJavaFileObjects (args);

This Iterableis then passed as an argument to the following method of JavaCompiler

to return a compilation task future:

JavaCompiler.CompilationTask getTask

(Writer out,JavaFileManager fileManager,DiagnosticListener<? super JavaFileObject> diagnosticListener,Iterable<String> options, Iterable<String> classes,

Iterable<? Extends JavaFileObject> compilationUnits)where:

• outidentifies a java.io.Writerto which additional compiler output is sent A nullargument implies System.err

• fileManageridentifies a file manager for abstracting files A nullargument impliesthe standard file manager

• diagnosticListeneridentifies a listener for receiving diagnostics A nullargumentimplies that the compiler’s default diagnostic-reporting mechanism is used

• optionsidentifies compiler options Pass nullif there are none

• classesidentifies the names of classes for annotation processing Pass nullif thereare none

• compilationUnitsidentifies what will be compiled A nullargument implies nocompilation units An IllegalArgumentExceptionis thrown from getTask()if any

of these compilation units are of a kind other than JavaFileObject.Kind.SOURCE.Continuing from the previous example, the following example invokes getTask()toreturn a compilation task future object that ultimately holds the compilation result Thisfuture object’s call()method is invoked to perform the compilation task:

compiler.getTask (null, sjfm, null, null, null, fileObjects).call ();

The example does not accomplish anything more than the previous run()method

To increase its usefulness, you can create a diagnostic listener (an object whose classimplements the DiagnosticListener<S>interface) and pass this listener to

getStandardFileManager()and getTask() Whenever a problem occurs during

compilation, this listener will be invoked to report the problem

Trang 18

Diagnostic Information

Instead of implementing DiagnosticListener<S>, you can create an instance of the more

convenient DiagnosticCollector<S>class, which collects diagnostics as a java.util.List<E>

of Diagnostic<S>s Following compilation, call the DiagnosticCollector<S>class’s

getDiagnostics()method to return this list For each Diagnostic<S>in the list, you would

then call various Diagnostic<S>methods to output diagnostic information This is

System.err.println ("usage: java CompileFiles2 srcFile [srcFile]+");

return;

}

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler ();

if (compiler == null){

System.err.println ("compiler not available");

sjfm = compiler.getStandardFileManager (dc, null, null);

Iterable<? extends JavaFileObject> fileObjects;

fileObjects = sjfm.getJavaFileObjects (args);

compiler.getTask (null, sjfm, dc, null, null, fileObjects).call ();

Trang 19

for (Diagnostic d: dc.getDiagnostics ()) {

System.out.println (d.getMessage (null));

System.out.printf ("Line number = %d\n", d.getLineNumber ());

System.out.printf ("File = %s\n", d.getSource ());

}

}}

The CompileFiles1and CompileFiles2applications focus on compiling Java sourcecode stored in files File-based compilation is not helpful if you want to compile sourcecode stored in a String

to the Compiler API After compilation, this application’s Testclass is loaded and its main()method is run

Trang 20

{System.err.println ("compiler not available");

Iterable<? extends JavaFileObject> fileObjects;

fileObjects = getJavaSourceFromString (program);

compiler.getTask (null, null, null, null, null, fileObjects).call ();

try{

Class<?> clazz = Class.forName ("Test");

Method m = clazz.getMethod ("main", new Class [] { String [].class });

Object [] _args = new Object [] { new String [0] };

m.invoke (null, _args);

}catch (Exception e){

System.err.println ("unable to load and run Test");

}}static Iterable<JavaSourceFromString> getJavaSourceFromString (String code){

final JavaSourceFromString jsfs;

jsfs = new JavaSourceFromString ("code", code);

return new Iterable<JavaSourceFromString> ()

{public Iterator<JavaSourceFromString> iterator (){

return new Iterator<JavaSourceFromString> (){

Trang 21

boolean isNext = true;

public boolean hasNext (){

return isNext;

}public JavaSourceFromString next (){

if (!isNext)throw new NoSuchElementException ();isNext = false;

return jsfs;

}public void remove (){

throw new UnsupportedOperationException ();}

};

}};

}}

class JavaSourceFromString extends SimpleJavaFileObject

{

final String code;

JavaSourceFromString (String name, String code){

super (URI.create ("string:///"+name.replace ('.', '/')+

Kind.SOURCE.extension), Kind.SOURCE);

this.code = code;

}public CharSequence getCharContent (boolean ignoreEncodingErrors){

return code;

}}

Trang 22

Although I’ve shown you how to use the Compiler API to overcome the “Java sourcecode must be stored in files” limitation, there is still the limitation of relying on tools.jar.

Fortunately, this limitation can be overcome by taking advantage of Java SE 6’s

Service-Loader API to access an alternate compiler, as you will learn in the “Extension

Mechanism and ServiceLoader API” section later in this chapter

I/O Enhancements

Little things often mean a lot Judging from the amount of comments to Bug 4050435

“Improved interactive console I/O (password prompting, line editing)” and Bug 4057701

“Need way to find free disk space,” many developers will be thrilled to discover that Java

SE 6 fixes these two long-standing bugs The first fix lets you safely prompt for passwords

without echoing them to the console (and more) The second fix lets you determine the

amount of free disk space (and more) Furthermore, Sun has also addressed a need for

setting a java.io.Fileobject’s read, write, and execute permissions by responding to

Bug 6216563 “Need capability to manipulate more file access attributes in File class.”

Note Java SE 6 has also fixed the I/O-related Bug 4403166 “File does not support long paths on

Windows NT.”

Console I/O

You are writing a console-based application that runs on the server This application

needs to prompt the user for a username and password before granting access

Obvi-ously, you do not want the password to be echoed to the console Prior to Java SE 6, you

had no way to accomplish this task without resorting to the Java Native Interface (JNI)

java.awt.TextFieldprovides a public void setEchoChar(char c)method to accomplish

this task, but this method is only appropriate for GUI-based applications

Java SE 6’s response to this need is a new java.io.Consoleclass This class providesmethods that access the character-based console device, but only if that device is associ-

ated with the current Java virtual machine (JVM) To determine if this device is available,

you need to call the Systemclass’s public static Console console()method:

Console console = System.console ();

Trang 23

This method returns a Consolereference if a console is present; otherwise, it returnsnull After verifying that the method did not return null, you can use the reference to callthe Consoleclass’s methods, which Table 2-1 describes

Table 2-1.Console Class Methods

Method Description

public void flush() Immediately writes all buffered output to the console.

public Console Writes a formatted string to the console’s output stream The format(String fmt, Console reference is returned so that you can chain method calls Object args) together (for convenience) Throws java.util.IllegalFormatException

if the format string contains illegal syntax.

public Console An alias for format().

printf(String format,

Object args)

public Reader reader() Returns the java.io.Reader associated with the console This Reader

can be passed to a java.util.Scanner constructor for more sophisticated scanning/parsing.

public String readLine() Reads a single line of text from the console’s input stream The line

(minus line-termination characters) is returned in a String However, if the end of the stream has been reached, it returns null Throws java.io.IOError if an error occurs during I/O.

public String Writes a formatted string to the console’s output stream, and then readLine(String fmt, reads a single line of text from its input stream The line (minus Object args) line-termination characters) is returned in a String However, if the

end of the stream has been reached, it returns null Throws IllegalFormatException if the format string contains illegal syntax Throws IOError if an error occurs during I/O.

public char[] Reads a password from the console’s input stream with echoing readPassword() disabled The password (minus line-termination characters) is

returned in a char array However, if the end of the stream has been reached, it returns null Throws IOError if an error occurs during I/O.

public char[] Writes a formatted string to the console’s output stream, and then readPassword(String fmt, reads a password from its input stream with echoing disabled The Object args) password (minus line-termination characters) is returned in a char

array However, if the end of the stream has been reached, it returns null Throws IllegalFormatException if the format string contains illegal syntax Throws IOError if an error occurs during I/O.

public PrintWriter Returns the java.io.PrintWriterassociated with the console.writer()

Trang 24

I have created an application that invokes Consolemethods to obtain a usernameand password Check out Listing 2-5 for the application’s source code.

System.err.println ("No console device is present");

return;

}try{

String username = console.readLine ("Username:");

char [] pwd = console.readPassword ("Password:");

// Do something useful with the username and password For something// to do, this program just prints out these values

System.out.println ("Username = " + username);

System.out.println ("Password = " + new String (pwd));

// Prepare username String for garbage collection More importantly,// destroy the password

username = "";

for (int i = 0; i < pwd.length; i++)pwd [i] = 0;

}catch (IOError ioe){

console.printf ("I/O problem: %s\n", ioe.getMessage ());

}}}

Trang 25

After obtaining and (presumably) doing something useful with the username andpassword, it is important to get rid of these items for security reasons Most important,you will want to remove the password by zeroing out the chararray.

If you have worked with the C language, you will notice the similarity between Console’s printf()method and C’s printf()function Both take a format string argument,which specifies format specifiers (such as %s), and follow this argument with a variablelist of arguments (one argument per specifier) To learn about the printf()method’s format specifiers, check out the java.util.Formatterclass’s JDK documentation

Disk Free Space and Other Partition-Space Methods

Obtaining the amount of free space on a disk is important to installers and other grams Until Java SE 6 arrived, the only portable way to accomplish this task was to guess

pro-by creating files of different sizes Java SE 6 remedied this situation pro-by adding three tion-space methods to File These methods are described in Table 2-2

parti-Table 2-2.File Class Partition-Space Methods

Method Description

public long getFreeSpace() Returns the number of unallocated bytes in the partition

identified by this File object’s abstract pathname Returns zero if the abstract pathname does not name a partition.

public long getTotalSpace() Returns the size (in bytes) of the partition identified by

this File object’s abstract pathname Returns zero if the abstract pathname does not name a partition.

public long getUsableSpace() Returns the number of bytes available to the current JVM

on the partition identified by this Fileobject’s abstract pathname Returns zero if the abstract pathname does not name a partition.

Although getFreeSpace()and getUsableSpace()appear to be equivalent, they differ

in the following respect: unlike getFreeSpace(), getUsableSpace()checks for write

permissions and other platform restrictions, resulting in a more accurate estimate

Note The getFreeSpace()and getUsableSpace()methods return a hint (not a guarantee) that a Java program can use all (or most) of the unallocated or available bytes These values are a hint because

a program running outside the JVM can allocate partition space, resulting in actual unallocated and availablevalues being lower than the values returned by these methods

Ngày đăng: 09/08/2014, 14:21

Nguồn tham khảo

Tài liệu tham khảo Loại Chi tiết
1. Under what condition is a cloned or serialized bitset not trimmed Khác
2. When you invoke close() on the Reader / PrintWriter objects returned by the Console class’s reader() / writer() methods, is the underlying stream closed Khác
3. Create a command-line utility that lets you make a file or directory read-only or writable Khác
4. What is the difference between the Deque&lt;E&gt; interface’s void addFirst(E e) and boolean offerFirst(E e) methods Khác
6. Use a copyOf() method to copy an array of String s to a new CharSequence array Khác
7. The ServiceLoader&lt;S&gt; class’s iterator() method returns an Iterator&lt;E&gt; whose hasNext() and next() methods are capable of throwing ServiceConfigurationError . Why throw an error instead of an exception Khác

TỪ KHÓA LIÊN QUAN