In this paper, the difference between jdk1.4,jdk1.5 and jdk1.6 in Java programming is analyzed with examples. Share to everyone for your reference, specific as follows:
Simply put:1.4 and 1.5 The biggest difference is two, one is 1.5 generics, another 1.5 can automatically encapsulate the eight basic data types of the package data type , that is, Integer a = 4 This 1.4 is not possible. the difference between 1.5 and 1.6 is small. 1.6 I think most of the changes, I think the biggest part is on the GUI, provides a lot of convenient layout management and extension .
This period of time into an e-government company, all with WEBLOGIC8, then we use jdk1.4 Bar, eclipse a JDK version, this is not the previous project is basically a red.
New features of ★jdk1.5:
1. Generic type
2 Automatic box/unboxing
3 For-each
4 Static Import
5 Variable length Parameters
1. Generics (avoid possible run-time errors caused by type casts)
For example:
ArrayList list=new ArrayList ();
List.add (New Integer (3));
List.add (New Integer (4));
int i= ((Integer) (List.get (0)). parseint ();
Very troublesome
Arraylist<integer>list=new arraylist<integer> ();
List.add (New Integer (3));
List.add (New Integer (4));
int I=list.get (0). parseint ();
2 Automatic box/unboxing
The last sentence of the above example could read:
Copy Code code as follows:
Because the original type is not explicitly converted from the corresponding wrapper class
3 For-each
The enhancement of the cycle
int a[]={........};//initialization for
(int i:a)
{
...
}
No previous i=0;i<a.length;i++.
4 Static Import
Previously tuned Java.math
Copy Code code as follows:
Now static import java.lang.Math.sqrt;
Again sqrt ();
It's the same way you do in your own class.
5 Variable length Parameters
int sum (int ... intlist)
{
int sum;
sum=0;
for (int i=0;i<intlist.length;i++)
{
sum+=intlist[i];
}
return sum;
}
Have any arguments, think of him as an array
★jdk6.0 new Features
Enhanced FOR Loop statement
Comments
Enumeration
A "hidden" static method
Variable parameters (VARARG)
Wildcard and covariant return
Enhanced FOR Loop statement
To iterate over collections and arrays, an enhanced for loop provides a simple, compatible syntax. There are two points worth mentioning:
First, in the loop, the initialization expression is evaluated only once. an int expression
Not enhanced for:
int sum = 0;
integer[] numbers = Computenumbers ();
for (int i=0 i < numbers.length; i++)
sum + = numbers[i];
Enhanced for:
int sum = 0;
for (int number:computenumbers ())
sum + = number;
Limitations
An iterator or subscript cannot be accessed during an enhanced for loop iteration
Take a look at the following example:
for (int i=0 i < numbers.length i++) {
if (I!= 0) System.out.print (",");
System.out.print (Numbers[i]);
This is another example:
for (iterator<integer> it = N.iterator (); It.hasnext ();)
if (It.next () < 0)
It.remove ();
Comments
Annotation processing is a big topic. Since this article focuses only on the language features of the core, we are not going to cover all of its possible forms and pitfalls. We will discuss the limitations of the built-in annotations (suppresswarnings,deprecated and override) and general annotation processing.
Suppress warnings
This comment closes the compiler warning at the class or method level. Sometimes you know better than the compiler that the code must use a deprecated method or perform some actions that cannot statically determine whether the type is safe, and use:
@SuppressWarnings ("deprecation") public
static void Selfdestruct () {
thread.currentthread (). Stop ();
}
This may be the most useful place for built-in annotations. Unfortunately, 1.5.0_04 's javac does not support it. But 1.6 supports it, and sun is trying to migrate it backwards into 1.5.
This annotation is supported in Eclipse 3.1 and may also be supported by other Ides. This allows you to completely release the code from the warning. If you have a warning at compile time, you can be sure that you just added it--to help you look at code that might be unsafe. As generics are added, it will be used more in the hand.
Deprecated
Unfortunately, deprecated is not so useful. It was intended to replace the @deprecated Javadoc tag, but since it does not contain any fields, there is no way to recommend what users of the deprecated class or method should use as a substitute. Most
Both Javadoc tags and this annotation are required for usage.
Override
Override says that the method it notes should override methods with the same signature in the superclass:
@Override public
int hashcode () {
...
}
Looking at the example above, if "C" is not capitalized in Hashcode, no error occurs at compile time, but the method will not be invoked as expected at run time. By adding the override tag, the compiler prompts whether it actually performs the override.
This is also helpful in situations where the superclass has changed. If you add a new parameter to the method and the method itself is renamed, the subclass will suddenly fail to compile because it no longer overrides anything in the superclass.
Other Notes
Annotations are useful in other scenarios. Annotations work very well in a framework such as EJB and Web services, especially if you are not modifying the behavior directly but enhancing the behavior, particularly when adding boilerplate code.
Annotations cannot be used as a preprocessor. Sun's design specifically prevents bytecode that modifies a class entirely because of annotations. This will correctly understand the language's results, and tools such as the IDE can perform in-depth code analysis and refactoring functions.
The note is not a silver bullet. When we first met, people tried to try all kinds of tricks. Take a look at the following advice from someone else:
public class Foo {
@Property
private int bar;
}
The idea is to automatically create getter and setter methods for private field bar. Unfortunately, the idea has two failures: 1 It can't run, 2 it makes the code difficult to read and process. It is not achievable because, as mentioned earlier, sun specifically prevents modifications to the classes that appear.
Even if it is possible, it is not a good idea because it makes the code less readable. The first person to see this code will not know that the annotation creates a method. In addition, annotations are useless if you need to do something inside these methods in the future. Anyway, don't try to use annotations to do things that regular code can do.
Enumeration
The enum is very much like the public static final int declaration, which has been used for many years as an enumeration value. The biggest and most obvious improvement to int is type safety--you can't mistakenly substitute one type of enumeration for another, which, unlike int, is the same for compilers. With very few exceptions, you should always replace the entire enumerated style int structure with an enum instance.
Enumeration provides some additional attributes. Enummap and Enumset These two practical classes are implemented specifically for the standard set of enumeration optimizations. If you know that the collection contains only enumerated types, you should use these specialized collections instead of HashMap or hashset.
In most cases, you can use an enum to insert replacements for all public static final int in your code. They are comparable and can be imported statically, so references to them appear to be equivalent, even for internal classes (or internal enumeration types). Note that when you compare enumerated types, the instructions that declare them indicate their order values.
A "hidden" static method
Two static methods appear in all enumerated type declarations. Because they are static methods on the enumeration subclass, rather than the methods of the enum itself, they do not appear in Java.lang.Enum Javadoc.
The first is values (), which returns an array of all possible values for an enumerated type.
The second is valueof (), which returns an enumerated type for the supplied string, which must precisely match the source code declaration.
Method
One of our favorite aspects about enumeration types is that it can have methods. In the past, you might want to write code that converts a public static final int to a JDBC URL from a database type. And now you can have the enumeration type itself with an integer
Method of code. Here is an example of an abstract method that includes the DatabaseType enumeration type and the implementation provided in each enumeration instance:
public enum DatabaseType {
ORACLE {public
string Getjdbcurl () {...}
},
MYSQL {public
string Getjdbcurl () {...}}
;
Public abstract String Getjdbcurl ();
}
Now the enumeration type can provide its practical method directly. For example:
DatabaseType DbType = ...;
String Jdbcurl = Dbtype.getjdbcurl ();
To get the URL, you must know in advance where the practical method is.
Variable parameters (VARARG)
It is true that you can clean up some junk code by using the variable parameters correctly. A typical example is a log method with the number of variable string parameters:
Log.log (String code)
Log.log (string code, string arg)
Log.log (string code, String arg1, string arg2)
Log.log (String code, string[] args)
When discussing variable parameters, it is interesting to be compatible if you replace the first four examples with the new variable parameters:
Copy Code code as follows:
Log.log (string code, string ... args)
All variable parameters are source-compatible-that is, if you recompile all of the calling programs for the log () method, you can replace all four methods directly. However, if backward binary compatibility is required, the first three methods need to be shed. Only the last method with a string array parameter is equivalent to a variable parameter version and can therefore be replaced with a variable parameter version.
Type cast
If you want the caller to know which type of argument should be used, you should avoid type casts with variable arguments. Looking at this example, the first hope is string, and the second hope is exception:
Log.log (Object... objects) {
String message = (string) objects[0];
if (Objects.length > 1) {
Exception e = (Exception) objects[1];
Do something with the exception
}
}
The method signature should look like the following, with the corresponding variable parameters using string and exception declarations, respectively:
Copy Code code as follows:
Log.log (String message, Exception E, Object ... objects) {...}
Do not use variable parameters to destroy type systems. It needs to be strongly typed before it can be used. For this rule, printstream.printf () is an interesting exception: it provides type information as its first argument, so that those types can be accepted later.
Covariant return
The basic use of covariant returns is to avoid type casts when the return type of an implementation is known to be more specific than the API. In the following example, there is a zoo interface that returns the animal object. Our implementation returns a Animalimpl object, but before JDK 1.5, it must be declared to return a animal object. :
Public interface Zoo {public
Animal getanimal ();
}
public class Zooimpl implements Zoo {public
Animal Getanimal () {return
new Animalimpl ();
}
}
The use of covariant return replaces three inverse modes:
Direct field access. To circumvent API restrictions, some implementations of the handle class are exposed directly to fields:
Copy Code code as follows:
Another form is to perform a downward conversion in the calling program, knowing that the implementation is actually a specific subclass:
Copy Code code as follows:
((Animalimpl) Zooimpl.getanimal ()). Implmethod ();
The last form I see is a concrete way to avoid problems caused by a completely different signature:
Copy Code code as follows:
These three models all have their problems and limitations. It is either not neat enough or exposes unnecessary details of implementation.
Co-change
The covariant return mode is clean, secure, and easy to maintain, and does not require a type cast or a specific method or field:
Public Animalimpl Getanimal () {return
new Animalimpl ();
}
Use result:
Copy Code code as follows:
Zooimpl.getanimal (). Implmethod ();
Using generics
We'll look at generics from two perspectives: using generics and constructing generics. We do not discuss the obvious usage of lists, sets, and maps. It is sufficient to know that a generic collection is powerful and should be used frequently.
We will discuss the use of generic methods and the methods of compiler inference types. Usually these things don't go wrong, but when something goes wrong, the error message is very confusing, so you need to know how to fix it.
Generic method
In addition to the generic type, Java 5 introduces a generic method. In this example from Java.util.Collections, a list of cells is constructed. The element type of the new list is inferred from the type of the object that passed in the method:
Copy Code code as follows:
Static <T> list<t> collections.singletonlist (T o)
Example usage:
Public list<integer> Getlistofone () {return
collections.singletonlist (1);
}
In the example usage, we passed in an int. So the return type of the method is list<integer>. The compiler infers T to be an integer. This is different from a generic type because you typically do not need to explicitly specify a type parameter.
This also shows the interaction of automatic boxing and generics. The type parameter must be a reference type: That's why we get list<integer> instead of list<int>.
Generic method with no parameters
The Emptylist () method is introduced with generics as a type-safe permutation of the Empty_list field in Java.util.Collections:
Copy Code code as follows:
Static <T> list<t> collections.emptylist ()
Example usage:
Public list<integer> Getnointegers () {return
collections.emptylist ();
}
Unlike the previous example, this method has no parameters, so how does the compiler infer the type of T? Basically, it will try to use one parameter at a time. If it does not work, it attempts to use the return or assignment type again. In this case, the LIST<INTEGER> is returned, so T is inferred to be Integer.
What happens if you call a generic method at a location other than a return statement or assignment statement? The compiler will not be able to perform the second pass of type inference. In the following example, Emptylist () is called from within the conditional operator:
Public list<integer> Getnointegers () {return
x? Collections.emptylist (): null;
}
Because the compiler does not see the return context and cannot infer T, it discards and takes object. You will see an error message, such as: "Cannot convert list<object> to list<integer>." ”
To fix this error, you should explicitly pass the type parameter to the method call. In this way, the compiler will not attempt to infer the type parameter, and the correct result can be obtained:
Copy Code code as follows:
return x? Collections.<integer>emptylist (): null;
Another place that happens frequently is in the method call. This syntax is also required if a method takes a list<string> parameter and needs to call the passed Emptylist () for that parameter.
Outside the collection
Here are three examples of generic types, which are not collections but rather use generics in a novel fashion. These three examples are from the standard Java library:
Copy Code code as follows:
Class is parameterized on the type of the class. This makes it possible to construct a newinstance without type casts.
Copy Code code as follows:
Comparable is parameterized by the actual comparison type. This provides a stronger type of CompareTo () invocation. For example, String implements Comparable<string>. Calling CompareTo () on anything other than a string will fail at compile time.
Copy Code code as follows:
An enum is parameterized by an enumerated type. An enumeration type named Color expands the enum<color>. The Getdeclaringclass () method returns the class object of the enumeration type, in this case a color object. It differs from GetClass (), which may return an unnamed class.
Wildcard characters
The most complex part of generics is the understanding of wildcard characters. We'll discuss three types of wildcard characters and their uses.
First let's look at how arrays work. You can assign a value from a integer[] to a number[. If you try to write a float to number[], you can compile it, but it will fail at run time, and a arraystoreexception appears:
Integer[] ia = new integer[5];
number[] na = ia;
Na[0] = 0.5; Compiles, but fails at runtime
If you attempt to convert this example directly to generics, you will fail at compile time because the assignment is not allowed:
list<integer> iList = new arraylist<integer> ();
list<number> nlist = iList; Not allowed
Nlist.add (0.5);
If you use generics, you will not encounter Run-time ClassCastException as long as the code does not appear to be warned at compile time.
Upper-bound wildcard character
What we want is a list of the exact element type unknown, which is different from the array.
List<number> is a list whose element type is the specific type number.
list<? Extends number> is an unknown list of exact element types. It is number or its subtype.
Ceiling
If we update the initial example and assign the value to List<? Extends Number>, the assignment is now successful:
list<integer> iList = new arraylist<integer> ();
list<? Extends number> nlist = iList;
Number n = nlist.get (0);
Nlist.add (0.5); Not allowed
We can get number from the list, because no matter what the exact element type of the list is (Float, integer, or number), we can assign it to number.
We still can't insert floating-point types into the list. This will fail at compile time because we cannot prove that this is safe. If we want to add a floating-point type to the list, it destroys the IList initial type security-it stores only integers.
Wildcard characters give us more expressive power than arrays.
Why use wildcard characters
In the following example, the wildcard character is used to hide type information from the user of the API. Internally, set is stored as Customerimpl. Users of the API only know that they are getting a set from which to read the customer.
Wildcard characters are required here because you cannot assign values from set<customerimpl> to set<customer>:
public class Customerfactory {
private set<customerimpl> _customers;
Public set<? Extends Customer> GetCustomers () {return
_customers;
}
}
Wildcard and covariant return
Another common usage of wildcard characters is to use with covariant returns. Rules with the same assignment can be applied to the covariant return. If you want to return a more specific generic type in the overridden method, the declared method must use a wildcard character:
Public interface Numbergenerator {public
list<? extends number> generate ();
}
public class Fibonaccigenerator extends Numbergenerator {public
list<integer> generate () {
...
}
}
If you want to use an array, the interface can return number[], and the implementation can return integer[].
Lower
What we are talking about is the upper bound wildcard. There is also a lower-bound wildcard character. list<? Super Number> is an unknown list of "element types", but may be a mnumber, or a super type of number. So it could be a list<number> or a list<object>.
Lower-bound wildcard Fu Yuan are not as common as upper-bound wildcard characters, but they are required when they are needed.
Lower limit and upper limit
list<? Extends number> readlist = new arraylist<integer> ();
Number n = readlist.get (0);
list<? Super number> writelist = new arraylist<object> ();
Writelist.add (New Integer (5));
The first is a list of readings that can be read from.
The second is a list of the numbers that can be written to it.
No bounds wildcard characters
The last,list<?> list can be any type of content, and it's list< with;? Extends object> almost the same. Object can be read at any time, but the contents cannot be written to the list.
Wildcard characters in the public API
In short, as mentioned earlier, wildcards are important to hide implementation details from callers, but even if the lower-bound wildcard appears to provide read-only access, it is not the case because of non-generic methods such as remove (int position). If you want a truly invariant set, you can use the Java.util.Collection method, such as Unmodifiablelist ().
Remember the wildcard character when you write the API. In general, you should try to use wildcards when passing generic types. It allows more callers to access the API.
by receiving list<? Extends number> instead of List<number>, the following method can be invoked by many different types of lists:
Copy Code code as follows:
void Removenegatives (list< extends number> List);
Constructing generic Types
Now we'll talk about constructing our own generic types. We'll show you some examples where you can improve type security by using generics, and we'll discuss some common problems when implementing generic types.
Collection-style (collection-like) functions
The first example of a generic class is a collection-style example. Pair has two type parameters, and the field is an instance of a type:
Public final class Pair<a,b> {public
final A;
Public final B second;
Public Pair (A, B second) {
this.first = i;
This.second = second;
}
This makes it possible to return two items from a method without having to write a dedicated class for each of the two types of combinations. Another approach is to return object[], which is either unsafe or untidy.
In the following usage, we return a file and a Boolean from the method. The client of the method can use the field directly without casting the type:
Public pair<file,boolean> getfileandwritestatus (String path) {
//create File and Status return
new Pair <File,Boolean> (File, status);
pair<file,boolean> result = Getfileandwritestatus ("...");
File f = result.first;
Boolean writeable = Result.second;
Outside the collection
In the following example, generics are used for additional compile-time security. By dbfactory the class parameter to the peer type you create, you are actually forcing the factory subclass to return a specific subtype of peer:
Public abstract class Dbfactory<t extends Dbpeer> {
protected abstract T createemptypeer ();
Public list<t> get (String constraint) {
list<t> peers = new arraylist<t> ();
Database Magic return
peers
}
}
You must return a Customer from Createemptypeer () by implementing Dbfactory<customer>,customerfactory:
public class Customerfactory extends dbfactory<customer>{public
Customer Createemptypeer () {return
new Customer ();
}
Generic method
You can use a generic method whether you want to impose constraints on a generic type between parameters or between parameters and return types:
For example, if you write a reversal function that reverses position, you may not need a generic method. However, if you want to reverse the return of a new list, you might want the element type of the new list to be the same type as the list you passed in. In this case, you need a generic method:
Copy Code code as follows:
<T> list<t> Reverse (list<t> List)
Specific
When implementing a generic class, you may want to construct an array of t[]. Because generics are implemented by Erasure (Erasure), this is not allowed.
You can try to cast object[] to t[. But it's not safe.
Materialized Solutions
As is customary in the generic tutorial, the solution uses the type token, and by adding a class<t> parameter to the constructor, you can force the client to provide the correct class object for the type parameter of the class:
public class Arrayexample<t> {
private class<t> clazz;
Public Arrayexample (class<t> clazz) {
this.clazz = clazz;
}
Public t[] GetArray (int size) {return
(t[]) array.newinstance (clazz, size);
}
In order to construct ARRAYEXAMPLE<STRING>, the client must pass String.class to the constructor because the String.class type is class<string>.
Owning a class object makes it possible to construct an array with the correct element type
I hope this article will help you with Java programming.