Tiger core library introduction

xiaoxiao2021-03-06  41

1.1. Properties of transactions

1.1.1. Access environment variables

Although Java has been launched from the spot, he repeatedly emphasized her cross-platform characteristics, "compiled, run everywhere". So the system.getenv () method that can access the platform proprietary information from the beginning to the Java's LANG package, it has been opposed by most people. Although some of these contents are abandoned in version 1.0, we can use this method in the Tiger version. Please note that all names of this method are lowercase.

The method used is simple: such as list 1

Public class envtest {

Public static void main (string args []) {

System.out.println (System.Getenv (Args [0]));

}

}

As long as the name of a given variable, it can be obtained.

Tiger provides two versions of GetENV (), the second version returns "name value" corresponding to all environment variables in the current settings. Listing 2 illustrates the use of this method:

Import java.util.map;

Public class envdump {

Public static void main (string args []) {

Map.Entry Entry: System.Getenv (). entryset ()) {

System.out.println (entry.getKey () "/" Entry.getValue ());

}

}

}

1.1.2. Accessing sub-process

The previous version of the J2SE platform provides the runtime class's EXEC () method to create a child process, in the Tiger version, this method is still valid, but in order to more convenient custom sub-process, Tiger provides the ProcessBuilder class, which makes the basis Changed process variables to create a child process is more convenient. ProcessBuilder provides a Directory (File) method to change the working directory of the process, add and delete environment variables in the process space with the Environment () method. Listing 3 illustrates the simple usage of Processor, which uses the ipconfig command to get Internet configuration information. This method is suitable for most platforms, otherwise IPConfig can be rewritten into the work commands on the platform used. After starting the process constructor, you need to get its InputStream to read the result of the created process.

Import java.io. *;

Public class processtest {

Public static void main (string args []) throws oException {

Process P = New ProcessBuilder ("ipconfig"). Start ();

InputStream IS = p.getinputStream ();

BufferedReader Br = New BufferedReader (NEW InputStreamReader (IS));

String line;

WHILE ((line = br.readline ())! = null) {

System.out.println (line);

}

}

}

Run results such as list 4:

Windows 2000 IP Configuration

Ethernet Adapter Local connection:

Connection-Specific DNS SUFFIX.:

.................: 10.97.69.166

Subnet mask........................

.......................................................... Adjust the context of the process before calling its START () method. If you don't like environment variables, you can use Environment to get the current setting and call Clear () Clear mapping. If you need to add an environment variable, you can call Environment to get the current setting, then add a new variable with PUT (Name, Value). If you want to use a new working directory, you can call Directory () and provide a new working directory as a File object. It is so simple.

To create ProcessBuilder using a string parameter that represents the number of variables that will run, the number of variables thereof, and you can call START () to execute the command once you use the new environment variable and the working directory to configure ProcessBuilder.

1.2. Concurrent Collection

The collection framework in Java has always been awarded, in Tiger, the collection framework has added a Queue interface and the concurrency and unconnection implementation of this interface, and the implementation of concurrent MAP and dedicated to read operations have exceeded write operation. The concurrent List and SET implementation in the case.

1.2.1. Queue interface

Although at both ends of the List can add deletion elements to achieve the performance of the simulated queue, Queue provides a more convenient way to support add, delete, and check a collection: such as Listing 5

Public Boolean Offer (Object Element)

Public Object Remove ()

Public Object Poll ()

Public Object Element ()

Public Object PEEK ()

Some queues have the limitations of size length, so if you want to join a new item in a full queue, you will be rejected. At this time, the new OFFER method can work. It is not a unchecked exception to call the add () method, but just get the false returned by Offer (). The REMOVE () and poll () methods are removed from the queue (head). Remove () behavior is similar to the version of the Collection interface, but the new poll () method does not throw an exception when calling with an empty set, just returning NULL. Therefore, new methods are more suitable for the case where abnormal conditions are prone to. The latter two methods Element () and peek () are used to query elements at the header of the queue. Similar to the remove () method, when the queue is empty, Element () throws an exception, and PEEK () returns NULL.

1.2.1.1. Basic queue implementation

1. In Tiger, java.util.LINKEDLIST has been transformed into two interfaces for java.util.list and java.util.Queue. Listing 6 shows simple use of LinkedList:

Queue queue = new linkedlist ();

Queue.offer ("one");

Queue.offer ("two");

Queue.offer ("three");

Queue.offer ("four");

System.out.println ("Head of queue is:" queue.poll ());

The result of the output should be ONE

2, UTIL package newly added AbstractQueue class, its working mode is similar to the AbstractList and AbstractSet class. When you need to create your own counterpart, you can directly inherit this class, you must implement offer (), poll (), peek () three Method, readers can provide optimized implementation. Readers can also create their own subclasses, but use several Tiger-provided implementations, two of which do not block queues: priorityQueue and ConcurrentLinkedQueue. The PriorityQueue class actually maintains an ordered queue, which is added to the Queue to sort in their natural order, and the basis for sorting is the implementation of the element to java.util.comParable or passed to the Queue constructor. Comparator parameters. If the specific implementation of Listing 6 is changed to PriorityQueue, the result of the input should be FOUR, because in alphabetical order, Four is the first one. ConcurrentlinkedQueue is a link-based queue based on link nodes. Concurrent access does not need to synchronize. Because it adds an element to the tail of the queue and deletes them from the head, there is no need to know the size of the queue, and ConcurrentLinkedQueue can work very well on public collection. Collecting information about the size of the queue will be slow and need to traverse queues. 1.2.1.2. Block queue implementation

The java.util.concurrent package provided by Tiger adds the BlockingQueue interface and five block queue classes in the collection framework. Simply put, the block queue means that when the queue is free, the add element's thread performs operational blocking, until there is space; or, when the queue is empty without element, execute the deleted thread blocked, know the element delete. The javadoc of the BlockingQueue interface gives the basic usage of blocking queues, as shown in Listing 7. The PUT () operation in the producer will block without space, while the consumer's Take () operation will block when there is no thing in the queue.

Class producer imports runnable {

PRIVATE FINAL BLOCKINGQUE Queue;

PROCKINGQUE q) {queue = q;}

Public void run () {

Try {

While (true) {queue.put (product ());

} catch (interruptexception ex) {... handle ...}

}

Object product () {...}

}

Class Consumer IMPLEments Runnable {

PRIVATE FINAL BLOCKINGQUE Queue;

CONSUMER (Blockingqueue q) {queue = q;}

Public void run () {

Try {

While (True) {consume (queue.take ());

} catch (interruptexception ex) {... handle ...}

}

Void Consume (Object X) {...}

}

Class setup {

Void main () {

BlockingQueue q = new somequeueImplementation ();

Producer P = New ProductER (q);

Consumer C1 = New Consumer (q);

Consumer C2 = New Consumer (q);

New thread (p) .start (); new thread (c1) .start ();

New Thread (C2) .start ();

}

}

The other five blocked queues are provided with different:

ArrayBlockingQueue: A bounded queue supported by arrays. LinkedBlockingQueue: An optional bound query supported by the link node. PriorityBlockingQueue: A unreasonable priority queue supported by priority stacks. DELAYQUEUE: A time-based dispatch queue supported by priority. SynchronousQueue: A simple gathering mechanism using the BlockingQueue interface

The first two class ArrayBlockingQueue and LinkedBlockingQueue are almost the same, but the LINKEDBLOCIKINGQUEUE does not always have capacity boundaries in the underlying storage implementation. LINKEDBLOCKINGQUEUE class with no size will never have block queues when adding an element (at least before it has an Integer.max_Value element, this time the capacity limit is Integer.max_Value).

PriorityBlockingQueue is a queue with unbreranged capacity, which uses the Comparable order sequencing order of the elements to logically sequentially maintained elements. It can be seen as a possibility for Treeset. For example, adding strings in the queue ONE, TWO, Three, and FOUR will result in FOUR to be taken out. For elements without natural sequence, a Compare can be provided for the constructor. However, it is important to note when priorityblockingQueue is used, and the Iterator instance returned from iTerator () does not necessarily return elements in priority order. If you must traverse all elements in priority order, let them sort them by the toarray () method, like arrays.sort (pq.toArray ()).

The new DELAYQUEUE implementation may be one of the most interesting (and most complex). Elements joining into the queue must implement a new Delayed interface (only one method - long getdelay (java.util.concurrent.timeUnit unit)). Because the queue size has no boundary, the addition can be returned immediately, but the elements cannot be removed from the queue before the delay time has passed. If multiple elements have completed delay, the earliest failure / failed time is the first to take the first. I actually didn't listen to this complicated. Listing 8 demonstrates the use of this new block queue collection:

Import java.util. *;

Import java.util.concurrent. *;

PUBLIC CLASS DELAY {

/ **

* Delayed Implementation That Actually Delays

* /

Static class nanodelay imports delayed {

Long Trigger;

Nanodelay (long i) {

Trigger = system.nanotime () i;

}

Public int compareto (Object Y) {

Long i = trigger;

Long J = (nanodelay) y) .trigger;

IF (i

IF (i> j) Return 1;

Return 0;

}

Public Boolean Equals (Object Other) {

Return (Nanodelay) .trigger == Trigger;}

Public Boolean Equals (Nanodelay Other) {

Return Other.trigger == Trigger;

}

Public long getdelay (timeUnit unit) {

Long n = trigger - system.nanotime ();

Return Unit.Convert (n, timeUnit.nanoseconds);

}

Public long Gettriggertime () {

Return Trigger;

}

Public string toString () {

Return String.Valueof (TRIGGER);

}

}

Public static void main (string args []) throws interruptedexception {

Random Random = new random ();

DELAYQUEUE Queue = New delayQueue ();

For (int i = 0; i <5; i ) {

Queue.Add (new nanodelay (random.nextint (1000)));

}

Long Last = 0;

For (int i = 0; i <5; i ) {

NanodeLay delay = (queue.take ());

Long TT = delay.gettriggertime ();

System.out.println ("Trigger Time:" TT);

IF (i! = 0) {

System.out.println ("Delta:" (TT - Last));

}

Last = TT;

}

}

}

This example is first is an internal class Nanodelay, which is substantially a number of nanoseconds, which utilizes the new nanotime () method of System. The main () method is then just putting the Nanodelay object in the queue and takes them again. If you want the queue item to do something else, you need to join the method in the implementation of the Delayed object, and call this new method after taking it from the queue. (Please extend Nanodelay to do some interesting things to add other methods.) Display the time difference between the two calls from the queue. If the time difference is a negative number, it can be considered an error, because it will never be taken from the queue from the queue after the delay time is over.

The SynchronousQueue class is the easiest. It has no internal capacity. It is like a hand hand mechanism between threads. Add an element in the queue to wait for another thread consumers. When this consumer appears, this element is directly transmitted between consumers and producers, never join the blocking queue.

1.2.2. ConcURRENTMAP implementation

The new java.util.concurrent.concurrentMap interface and the ConcurrentHashMap implementation can only be added to the map when the key does not exist, and one element can be removed from the MAP when the key is present and mapped to a particular value.

There is a new PutifabSent () method in ConcurrentMap to add in MAP. This method is to add the keys and values ​​to the CONCURENTMAP implementation, just like a normal PUT () method, but only the keys can be added to the MAP only when the MAP does not contain this button. If the Map already contains this button, the existing value of this button will return. This operation is equal to the code of the Listing 9: if (! Map.containskey (key))

Return map.put (key, value);

Else

Return map.get (key);

Like the powging () method, the Remove () method after the overload is two parameters - keys and values. When the call is called, this button is removed from the MAP when the key is mapped to the specified value. If you don't match, then this button is not deleted and returns false. If the value matches the current map content of the key, then the key is removed. Listing 10 shows the equivalent source code for this operation:

IF (Map.get (key) .Equals (value) {

Map.Remove (key);

Return True;

} else {

Return False;

}

1.2.3. CopyonWriteArrayList and CopyonWriteArrayset

The Copy-On-Write mode is declared, in order to maintain the consistency snapshot of the object, relying on the immutability to eliminate synchronization required when coordinated different but related properties. For collection, this means that if there is a lot of read (ie, get ()) and iteration, it is not necessary to simultaneously operate to take care of the occasional write (ie the add ()) call. For new CopyonWriteArrayList and CopyonWriteArraySet classes, all variable operations first get a copy of the rear array, change the copy, and then replace the copy. This approach guarantees that when traversing the collection of itself, never throws the ConcurrentModificationException. The traversal collection will be done with the original set, while the updated collection is used in later operations.

These new collections, CopyonWriteArrayList, and CopyonWriteArraySet, most suitable for read operations, usually, greatly exceeded the write operation. One most commonly mentioned example is to use a list of listeners. It has been said that the Swing component has not been changed to the use of new collections. Instead, they continue to use javax.swing.event.eventListenerList to maintain their listener lists.

As shown in Listing 11, the use of the collection is exactly the same as their non-Copy-ON-WRITE alternatives. Just create a collection and add or delete an element therein. Even if the object is added to the collection, the original Iterator can also perform, continue to traverse the items in the original collection.

Import java.util. *;

Import java.util.concurrent. *;

Public class copyonwrite {

Public static void main (string args []) {

List List1 = New CopyonWriteArrayList (Arrays.ASLIST (ARGS));

List list2 = new arraylist (arrays.aslist (args));

Iterator itor1 = list1.iterator ();

Iterator itor2 = list2.iterator ();

List1.add ("new"); list2.add ("new");

Try {

Printall (ITOR1);

} catch (concurrentModificationException e) {

System.err.Println ("Shouldn't get here");

}

Try {

Printall (ITOR2);

} catch (concurrentModificationException e) {

System.err.Println ("Will Get Here.");

}

}

Private static void printall (iterator itor) {

While (itor.hasnext ()) {

System.out.println (ITOR.Next ());

}

}

}

This sample program creates two instances of CopyonWriteArrayList and Arraylist with command line parameters. After getting the Iterator of each instance, an element is added therein. When ArrayList iteration is immediately stopped by a ConcURRentModificationException problem, CopyonWriteArrayList iteration can continue without throwing an exception, because the original collection is changed after Iterator. If this behavior (such as notifying all elements in a set of event listeners) is what you need, it is best to use a Copy-ON-WRITE collection. If you don't use it, use the original and guarantee that it will be processed when an abnormality occurs.

1.3. Formatter

For those who have never been exposed to C from the start of Java programming from the beginning, or those who do not know enough to C, formatted strings are some weird text strings, which specifies the output characteristics of a set of variables. Not to connect the string with the plus sign (such as firstname " lastname), but provide a string description output, and provides parameters to replace the placeholders in the string when the method call is completed: String S = String.Format ("% 1 $ S% 2 $ S", firstname, lastname).

First, let us analyze the new Java.util.formatter class. You may not use this class directly, but it provides the formatted internal mechanism to be performed. In this class's Javadoc, a table describing the supported formatting options will be seen. These options range from similar to%

7.4f

Such format specifies the accuracy and bits of the floating point number, to% TT of formatted time, to format the third parameter% 3 $ S.

Format the output is divided into two steps: Create an Appendable object to store the output, put the contents of the format in this object with the Format () method. The implementation of the Appendable interface is listed below:

BufferedWriter ChararrayWriter Charbuffer FileWriter FilterWriter Logstream OutputStreamWriter PiredWriter PrintStream PrintWriter StringBuffer StringBuilder StringWriter Writer

When using the Formatter class, the object that implements this interface can be passed to the constructor formatter to use it as a target. Most of these classes look very similar, except for the StringBuilder class. StringBuilder is almost the same as the StringBuffer class, only one big difference: it is not a thread safe. Use StringBuilder if you know to build a string in a single thread. Use StringBuffer if the build process spans multiple threads. Listing 12 shows how typically start using formatter: StringBuilder SB = New StringBuilder ();

Formatter formatter = new formatter (SB, local.us);

After creating the Formatter class, the format () method is called with formatted strings and parameters. If you need to use different Locale delivered to the constructor as part of the formatted output, you can also pass a Locale object to the Format () method. Listing 13 shows two different format ():

Public Formatter Format (String Format, Object ... ARGS)

Public Formatter Format (Locale L, String Format, Object ... ARGS)

If you want to get a PI value of 10 digits, the code in Listing 14 will put this value into the StringBuilder and print out. Printing the Formatter object will display the contents of the Appendable object.

Import java.util.locale;

Import java.util.formatter;

Public class build {

Public static void main (string args []) {

Stringbuilder SB = New StringBuilder ();

Formatter formatter = new formatter (SB, local.us);

Formatter.format ("pi =%

12.10f

"Math.pi);

System.out.println (Formatter);

}

}

1.3.1. PrintStream support

A common in the PrintStream class is defined, which is used to write the System.out and System.err objects that are written to standard outputs and standard errors, respectively. TiGer introduces two new constructor (for direct writing files) and six ways to provide support for formatting (three pairs). The first pair is another version of the append () method. This pair method implements a new java.lang.Appendable interface. These methods are generally not called directly. Direct calls are format () and printf (), where the printf () version is just the convenient wrapper of the Format () version, as shown in Listing 15:

Public PrintStream Format (String Format, Object ... ARGS)

Public PrintStream Format (LOCALE L, STRING FORMAT, Object ... ARGS)

To remember the new variable parameter support, it is assigned

Listing 16 demonstrates the date of printstream's format () method:

Import java.util.calendar;

Public class now {

Public static void main (string args []) {

System.out.Format ("Today IS% 1 $ TE." Calendar.GetInstance ());}

}

The output running this program is Today Is January 19, 2005. Of course, the actual output depends on the date that runs this program. The formatted string% 1 $ TB tells the program with the first parameter and print the full mine name of the Date object. Formatted Strings% 1 $ TE means the date of the month, and the formatted string% 1 $ T is the year of the four digits. Other options for printing the date are listed in the Javadoc in the Formatter object.

1.3.2. String support

The String class has two new Static Format () methods, and their roles are similar to the corresponding printf (). Send a format string and parameters (possibly there may be locale) and use the format conversion parameters specified in the format string. If it is the String version of this method, then the result is not the result of the String object instead of the stream. These methods are not very conspicuous, but they can avoid directly using the formatter object and create the StringBuilder in the middle.

1.3.3. Format any object

Each of the items seen so far is to describe how to use new formatting capabilities to format existing objects and basic data. If you want to provide support for your own object with formatter, then use the FormatTable interface. By implementing a FormatTo () method shown in its own class, you can use the formatted string for your own class:

Void Formatto (Formatter Formatter, Int Flags, INTEGER WIDTH, INTEGER Precision)

Listing 18 demonstrates the formatTable interface by providing a simple class with an NAME attribute. This name is displayed in the output that supports the width and alignment of the output.

Import java.util.locale;

Import java.util.formatter;

Import java.util.formattable;

Public class myObject imports formattable {

String name;

Public myObject (string name) {

THIS.NAME = Name;

}

Public void formatto

Formatter FMT,

Int f,

Integer Width,

Integer precision) {

Stringbuilder SB = New StringBuilder ();

IF (precision == null) {

// no max width

Sb.append (name);

} else if (name.length ()

Sb.append (name);

} else {

Sb.append (name.substring (0, precision - 1)). Append ('*');

}

// Apply Width and Justification

IF ((width! = null) && (sb.length ()

For (int i = 0, n = sb.Length (); i

IF ((F & formatTable.Left_justify) == formattable.left_justify) {

sb.append ('');

} else {

sb.insert (0, '');

}

}

FMT.FORMAT (sb.toString ());

}

Public static void main (string args []) {

MyObject my1 = new myObject ("john");

MyObject my2 = new myObject ("really long name");

// first / using toString ()

System.out.println ("First Object: MY1);

// second / using formatter

System.out.format ("First Object: '% s' // n", MY1);

// second / using formatter

System.out.Format ("Second Object: '% s' // n", my2);

// second / using formatter with width

System.out.Format ("Second Object: '% 10.5s' // n", my2);

// Second / use formatter with width and left justification

System.out.Format ("Second Object: '% -10.5s' // n", my2);

}

}

Run this program generates the output as shown in Listing 19. The first two lines show different results using Tostring and Formatter. The width and alignment control options are displayed.

First Object: myObject @ 10b

62C

9

First Object: 'John'

Second Object: 'Really Long Name'

Second Object: 'REAL *'

Second Object: 'REAL *

1.4. Loading attributes from XML files

Properties This class should not be unfamiliar with the reader, most of which use this attribute text file in the application's configuration file. In Tiger, the Java.util.Properties class now provides a easier way to load and store settings: LoadFromXML (InputStream IS, String Comment) method.

1.4.1. XML attribute file

The specified DTD of the XML property file is shown in Listing 20:

Simple XML attribute files are shown in Listing 21:

hi

bar

baz

I believe that the reader is at this point.

1.4.2. Access XML attribute file

1.4.2.1. Read the XML attribute file

Reading the XML version of the Properties file is nothing different from the file read old format. As shown in Listing 22

Import java.util. *;

Import java.io. *;

Public class loadsamplexml {

Public static void main (string args []) throws exception {

Properties Prop = New Properties ();

FileInputStream Fis = New FileInputStream ("SampleProps.xml");

Prop.LoadFromXML (FIS);

Prop.List (System.out);

System.out.println ("/ NTHE Foo Property:" Prop.GetProperty ("foo"));

}

}

1.4.2.2. Save the XML property file

Create an XML file with a new StoreToxml () method. Just deliver an OutputStream and a string for comments. The code is shown in Listing 23:

Import java.util. *;

Import java.io. *;

Public class storexml {

Public static void main (string args []) throws exception {

Properties Prop = New Properties ();

Prop.SetProperty ("One-TWO", "Buckle My Shoe");

Prop.SetProperty ("Three-Four", "Shut the Door");

Prop.SetProperty ("Five-Six", "PICK UPS");

Prop.SetProperty ("Seven-Eight", "Lay The Straight");

Prop.SetProperty ("Nine-Ten", "A Big, Fat Hen");

FileOutputStream Fos = New FileOutputStream ("rhyme.xml");

Prop.StoreToxml (FOS, "Rhyme");

Fos.close ();

}

}

The results of the operation are shown in Listing 24:

rhyme

Lay the straight PICK UPSES

a big, fat hen

Shut the door

buckle my shoe

1.5. Other core libraries enhancements

In addition, there is a certain increase in the core library of Tiger. Due to the space limit, this is not described here. Please feel interested in the relevant content of the JDK 5.0 API Documentation.

1.5.1. Scanner

The Java.util.Scanner class can be used to convert text into primitives or strings. Since it is based on a java.util.regex package, it also provides a way to manage regular expressions, which makes the search in the stream, file data, string, or readable interface package behavior (IMPLEMENTOR) .

1.5.2. JavaBeans component architecture

A PropertyChangeEvent subclass called IndexedPropertyChangeEvent has been added to support the limits attribute, which uses an index to point out the BEAN's change section. In addition, some methods have been added to the PropertyChangeSupport class to support excitation index properties change events.

1.5.3. MATH package

The Java.math package contains the following enhancements:

· The BigDecimal class has added support for fixed precision floating point calculations. See JSR 13.

· MATH and STRICTMATH libraries include dual curves transcendent function (SINH, COSH and TANH), cube roots, and 10-based logarithms.

· Hexen Floating point support - to allow specific floating point values ​​to be accurate and predictable, hexadecimal representation can be used for the literal value of floating point numbers, as well as for Float and Double floating point digital conversion methods String.

1.5.4. Network

1.5.5. Security

This version of J2SE has greatly enhanced security. It provides better support for security tokens, providing support for more security standards (SASL, OCSP, and TSP), improved scalability, and performance, which also provides in Crypto and Java GSS. Many enhancements. For more information, see the link above.

1.5.6. Internationalization

Enhancements are:

· The character processing is now based on a version 4.0 of Unicode standard. This affects the Character class in the java.lang package, the Sword Rule in the Java.Text package, and the two-way text analysis feature, the Character class in the java.util.Regex package, and many of the other parts of J2SE. As part of this upgrade, JSR 204 Expert Group has specified support for assist characters, and it has implemented this support throughout J2SE. See JSR 204 or CHARACTER class documentation for more information.

· The DecimalFormat class has been enhanced, and it is now possible to format and parse the BigDecimal and Biginteger values ​​without losing accuracy. Formatting of these values ​​is automatically enhanced; the setParseBigDecimal method must be enabled to be parsed to BigDecimal. · Now, Vietnamese has been supported in java.util and all local locale sensitive features in Java.util and Java.Text packages. For complete information about supported Locale and write systems, see Support Locale.

1.5.7. Serialization

Support has been added to handle new enumeration types in version 1.5. Serialized an enumeration instance specifies those rules that are serialized a "normal" sequential object: The serialization form of the enumeration instance consists of only its enumeration, and the information of its basic enumeration type is included. Define behavior is also different-class information for finding a corresponding enumeration class, and to acquire the returned enumeration constant, invoke the enum.valueof method by using that class and the received constant name.

1.6. Conclusion

The above is only a small part of the J2SE 1.5 core library new features, and there are many other new features that are limited to the paradodel. Interested in further understanding of these new features readers can see http: // java. Sun.com/j2se/

1.5.0

/DOCS/Relnotes/features.html Get more information.

"By enhancing the power of the Java platform, the developers allow developers to be easier to use, and these improvements in Java programming will attract a large number of Java developers", which is an important milestone for the development of Java technology. "

转载请注明原文地址:https://www.9cbs.com/read-59322.html

New Post(0)