Introduction to Java model

Source: Internet
Author: User
General Linux technology-Linux programming and kernel information. In the released Java1.4, many new APIs (such as Loging, regular expressions, and NIO) are added to the core code library, many APIs have been added in the latest JDK1.5 and JDK1.6 to be released, among which Generics (model) is of great significance ).

1. What is Generics?

Generics can be called parameterized types. The Compiler verifies the mechanism by which a type is transmitted to an object from the client. Such as Java. util. ArrayList,

The compiler can use Generics to ensure type security.
Before learning about Generics, let's take a look at the current java Collection framework (Collection ). In j2SE1.4, The Root Interface of all sets is Collection.

Collections example without genericity: Example 1


1 protected void collectionsExample (){
2 ArrayList list = new ArrayList ();
3 list. add (new String ("test string "));
4 list. add (new Integer (9); // purposely placed here to create a runtime ClassCastException
5 inspectCollection (list );
6}
7
8
9 protected void inspectCollection (Collection aCollection ){
10 Iterator I = aCollection. iterator ();
11 while (I. hasNext ()){
12 String element = (String) I. next ();
13}
14}



The preceding example contains two methods. The collectionExample method creates a simple set-type ArrayList and adds a String and an Integer object to the ArrayList. in the inspecCollection method, we iterate this ArrayList and use String for Cast. We can see that the second method has a problem. The Collection uses an Object internally. to retrieve the objects in the Collection, we need to perform Cast, the developer must use the actual type for Cast. For example, the compiler does not

In this way, we are at risk of throwing ClassCastException during code execution. We can see that the inspecCollection method has no problem during compilation, but the ClassCastException will be thrown during runtime. So we must stay away from this major runtime error.


Ii. Use Generics
From the exception of CassCastException in the previous chapter, we expect to be able to capture it during code compilation. Below we use the paradigm to modify the sample program in the previous chapter.
// Example 2

1 protected void collectionsExample (){
2 ArrayList List = new ArrayList ();
3 list. add (new String ("test string "));
4 // list. add (new Integer (9); this no longer compiles
5 inspectCollection (list );
6}
7
8
9 protected void inspectCollection (Collection ACollection ){
10 Iterator I = aCollection. iterator ();
11 while (I. hasNext ()){
12 String element = I. next ();
13}
14}



From the above 2nd rows, we used the new syntax when creating the ArrayList, and added the Generics Declaration to all collections in JDK1.5. Example:
// Example 3

1 public class ArrayList Extends actlist {
2 // details omitted...
3 public void add (E element ){
4 // details omitted
5}
6 public Iterator Iterator (){
7 // details omitted
8}
9}



This E is a type variable and does not define specific types. It is just a type placeholder when defining ArrayList. in Example 2, we define the ArrayList

In this example, we use String to bind to E. When we use the add (E element) method to add an object to ArrayList, it is like the following statement: public void add (String element); because all methods in ArrayList use String to replace E, whether it is a method parameter or a return value. Now let's look at the fourth line in Example 2, and the compilation will reflect the compilation error.
Therefore, the main purpose of adding Generics in java is to increase type security.

Through the simple example above, we can see the advantages of using Generics:
1. Collection is type-safe when the type does not change.
2. The internal type conversion is better than the external manual shape.
3. Make the Java interface stronger, because it adds the type.
4. type Matching errors can be captured at the compilation stage, rather than during code running.

Variable of constrained type
Although many classes are designed to Generics, type variables can be limited.
Public class C1 {}
Public class C2 {}
The first T variable must inherit the Number, and the second T must inherit the Person and implement the Comparable

Iii. Generics Method

Like the Generics class, methods and constructors can also have type parameters. The return values of method parameters can all have type parameters for Generics.
// Example 4

1 public T max (T t1, T t2 ){
2 if (t1.compareTo (t2)> 0)
3 return t1;
4 else return t2;
5}



Here, the parameter type of the max method is a single T type, while the T type inherits Comparable. The parameters and return values of max have the same superclass. The following Example 5 shows the constraints of the max method.
// Example 5

1 Integer iresult = max (new Integer (100), new Integer (200 ));
2 String sresult = max ("AA", "BB ");
3 Number nresult = max (new Integer (100), "AAA"); // does not compile



In Example 5 1st, the parameters are all Integer, so the return value is also Integer. Note that the return value is not modeled.
In Example 5 2nd, the parameters are both strings, so the returned value is also String. Note that the returned value is not modeled. The same method is called.
The following compilation errors are generated in line 5 of Example 5:
Example. java: 10: incompatible types
Found: java. lang. Object & java. io. Serializable & java. lang. Comparable
Required: java. lang. Number
Number nresult = max (new Integer (100), "AAA ");

This error occurs because the compiler cannot determine the type of the returned value, because both String and Integer have the same super-Class Object. Note that even if we fix the third line, this line of code still reports an error while running, because different objects are compared.

Iv. Backward compatibility
When any new feature comes out of the new JDK version, we first care about how to be compatible with the previously written code. That is to say, the Example 1 program we compile can run without any changes, but the compiler will give a warning of "row type. How can the code written in JDK1.4 be fully compatible with JVM1.5? We need to perform a manual process: Type erasure.

5. wildcard characters

// Example 6

List StringList = new ArrayList (); // 1
List ObjectList = stringList; // 2
ObjectList. add (new Object (); // 3
String s = stringList. get (0); // 4



At first glance, Example

6 is correct. However, the stringList is intended to store the ArrayList of the String type, while the objectList can store any object. when processing the String type in Row 3, The stringList cannot be guaranteed to be an ArrayList of the String type, at this time, the compiler does not allow such a problem, so the 3rd rows cannot be compiled.

// Example 7

Void printCollection (CollectionC)
{For (Object e: c ){
System. out. println (e );
}}



The purpose of Example 7 is to print all Collection objects, but as Example 6 said, an error will be reported during compilation, so you can use the wildcard "?" To modify Example 7

// Example 8

Void printCollection (Collection C)
{For (Object e: c ){
System. out. println (e );
}}



All Collection types in Example 8 can be conveniently printed.

Bounded wildcard (Upper Bound) (Lower Bound)

6. Create your own Model
The following code comes from the http://www.java2s.com/ExampleCode/Language-Basics
1. Generics OF A PARAMETER
// Example 9 (no fan type is used)

Class NonGen {
Object ob; // ob is now of type Object
// Pass the constructor a reference
// An object of type Object
NonGen (Object o ){
Ob = o;
}
// Return type Object.
Object getob (){
Return ob;
}
// Show type of ob.
Void showType (){
System. out. println ("Type of ob is" +
Ob. getClass (). getName ());
}
}
// Demonstrate the non-generic class.
Public class NonGenDemo {
Public static void main (String args []) {
NonGen iOb;
// Create NonGen Object and store
// An Integer in it. Autoboxing still occurs.
IOb = new NonGen (88 );
// Show the type of data used by iOb.
IOb. showType ();
// Get the value of iOb.
// This time, a cast is necessary.
Int v = (Integer) iOb. getob ();
System. out. println ("value:" + v );
System. out. println ();
// Create another NonGen object and
// Store a String in it.
NonGen strOb = new NonGen ("Non-Generics Test ");
// Show the type of data used by strOb.
StrOb. showType ();
// Get the value of strOb.
// Again, notice that a cast is necessary.
String str = (String) strOb. getob ();
System. out. println ("value:" + str );
// This compiles, but is conceptually wrong!
IOb = strOb;
V = (Integer) iOb. getob (); // runtime error!
}
}



// Example 10 (use the Model)

Class Example1 {
Private T t;
Example1 (T o ){
This. t = o;
}
T getOb (){
Return t;
}
Void ShowObject (){
System. out. println ("Object Type:" + t. getClass (). getName ());
}
}
Public class GenericsExample1 {

/**
* @ Param args
*/
Public static void main (String [] args ){
// TODO Auto-generated method stub
Example1 Examplei = new Example1 (100 );
Examplei. ShowObject ();
System. out. println ("Object:" + examplei. getOb ());
Example1 Examples = new Example1 ("Bill ");
Examples. ShowObject ();
System. out. println ("Object:" + examples. getOb ());
}

}



We can see that Example 9 does not use the model, so we need to shape, while Example 10 does not need any shape.

2. Generics of the two parameters

// Example 11

Class TwoGen {
T ob1;
V ob2;
// Pass the constructor a reference
// An object of type T.
TwoGen (T o1, V o2 ){
Ob1 = o1;
Ob2 = o2;
}
// Show types of T and V.
Void showTypes (){
System. out. println ("Type of T is" +
Ob1.getClass (). getName ());
System. out. println ("Type of V is" +
Ob2.getClass (). getName ());
}
T getob1 (){
Return ob1;
}
V getob2 (){
Return ob2;
}
}

Public class GenericsExampleByTwoParam {

/**
* @ Param args
*/
Public static void main (String [] args ){
// TODO Auto-generated method stub
TwoGen TgObj =
New TwoGen (88, "Generics ");
// Show the types.
TgObj. showTypes ();
// Obtain and show values.
Int v = tgObj. getob1 ();
System. out. println ("value:" + v );
String str = tgObj. getob2 ();
System. out. println ("value:" + str );
}

}



3. Generics Hierarchy

// Example 12

Class Stats {
T [] nums; // array of Number or subclass
// Pass the constructor a reference
// An array of type Number or subclass.
Stats (T [] o ){
Nums = o;
}
// Return type double in all cases.
Double average (){
Double sum = 0.0;
For (int I = 0; I <nums. length; I ++)
Sum + = nums . DoubleValue ();
Return sum/nums. length;
}
}
Public class GenericsExampleByHierarchy {


/**
* @ Param args
*/
Public static void main (String [] args ){
// TODO Auto-generated method stub

Integer inums [] = {1, 2, 3, 4, 5 };
Stats Iob = new Stats (Inums );
Double v = iob. average ();
System. out. println ("iob average is" + v );
Double dnums [] = {1.1, 2.2, 3.3, 4.4, 5.5 };
Stats Dob = new Stats (Dnums );
Double w = dob. average ();
System. out. println ("dob average is" + w );
// This won't compile because String is not
// Subclass of Number.
// String strs [] = {"1", "2", "3", "4", "5 "};
// Stats Strob = new Stats (Strs );
// Double x = strob. average ();
// System. out. println ("strob average is" + v );
}
}



4. Use wildcards
// Example 14

Class StatsWildCard {
T [] nums; // array of Number or subclass
// Pass the constructor a reference
// An array of type Number or subclass.
StatsWildCard (T [] o ){
Nums = o;
}
// Return type double in all cases.
Double average (){
Double sum = 0.0;
For (int I = 0; I <nums. length; I ++)
Sum + = nums . DoubleValue ();
Return sum/nums. length;
}
// Determine if two averages are the same.
// Notice the use of the wildcard.
Boolean sameAvg (StatsWildCard Ob ){
If (average () = ob. average ())
Return true;
Return false;
}
}

Public class GenericsExampleByWildcard {

/**
* @ Param args
*/
Public static void main (String [] args ){
// TODO Auto-generated method stub
Integer inums [] = {1, 2, 3, 4, 5 };
StatsWildCard Iob = new StatsWildCard (Inums );
Double v = iob. average ();
System. out. println ("iob average is" + v );
Double dnums [] = {1.1, 2.2, 3.3, 4.4, 5.5 };
StatsWildCard Dob = new StatsWildCard (Dnums );
Double w = dob. average ();
System. out. println ("dob average is" + w );
Float fnums [] = {1.0F, 2.0F, 3.0F, 4.0F, 5.0F };
StatsWildCard Fob = new StatsWildCard (Fnums );
Double x = fob. average ();
System. out. println ("fob average is" + x );
// See which arrays have same average.
System. out. print ("Averages of iob and dob ");
If (iob. sameAvg (dob ))
System. out. println ("are the same .");
Else
System. out. println ("differ .");
System. out. print ("Averages of iob and fob ");
If (iob. sameAvg (fob ))
System. out. println ("are the same .");
Else
System. out. println ("differ .");

}

}



5. Use the boundary wildcard
// Example 15

Class TwoD {
Int x, y;
TwoD (int a, int B ){
X =;
Y = B;
}
}
// Three-dimen1_coordinates.
Class ThreeD extends TwoD {
Int z;
ThreeD (int a, int B, int c ){
Super (a, B );
Z = c;
}
}
// Four-dimen=coordinates.
Class FourD extends ThreeD {
Int t;
FourD (int a, int B, int c, int d ){
Super (a, B, c );
T = d;
}
}
// This class holds an array of coordinate objects.
Class Coords {
T [] coords;
Coords (T [] o) {coords = o ;}
}
// Demonstrate a bounded wildcard.
Public class BoundedWildcard {
Static void showXY (Coords C ){
System. out. println ("x y Coordinates :");
For (int I = 0; I <c. coords. length; I ++)
System. out. println (c. coords . X + "" +
C. coords. Y );
System. out. println ();
}
Static void showXYZ (Coords C ){
System. out. println ("x y z Coordinates :");
For (int I = 0; I <c. coords. length; I ++)
System. out. println (c. coords. X + "" +
C. coords. Y + "" +
C. coords. Z );
System. out. println ();
}
Static void showAll (Coords C ){
System. out. println ("x y z t Coordinates :");
For (int I = 0; I <c. coords. length; I ++)
System. out. println (c. coords. X + "" +
C. coords. Y + "" +
C. coords. Z + "" +
C. coords. T );
System. out. println ();
}
Public static void main (String args []) {
TwoD td [] = {
New TwoD (0, 0 ),
New TwoD (7, 9 ),
New TwoD (18, 4 ),
New TwoD (-1,-23)
};
Coords Tdlocs = new Coords (Td );
System. out. println ("Contents of tdlocs .");
ShowXY (tdlocs); // OK, is a TwoD
// ShowXYZ (tdlocs); // Error, not a ThreeD
// ShowAll (tdlocs); // Erorr, not a FourD
// Now, create some FourD objects.
FourD fd [] = {
New FourD (1, 2, 3, 4 ),
New FourD (6, 8, 14, 8 ),
New FourD (22, 9, 4, 9 ),
New FourD (3,-2,-23, 17)
};
Coords Fdlocs = new Coords (Fd );
System. out. println ("Contents of fdlocs .");
// These are all OK.
ShowXY (fdlocs );
ShowXYZ (fdlocs );
ShowAll (fdlocs );
}
}




6. Generics of ArrayList
// Example 16

Public class ArrayListGenericDemo {
Public static void main (String [] args ){
ArrayList Data = new ArrayList ();
Data. add ("hello ");
Data. add ("goodbye ");

// Data. add (new Date (); This won't compile!

Iterator It = data. iterator ();
While (it. hasNext ()){
String s = it. next ();
System. out. println (s );
}
}
}



7. Generics of HashMap
// Example 17

Public class HashDemoGeneric {
Public static void main (String [] args ){
HashMap Map = new HashMap ();

Map. put (1, "Ian ");
Map. put (42, "Scott ");
Map. put (123, "Somebody else ");

String name = map. get (42 );
System. out. println (name );
}
}



8. Generics OF THE INTERFACE
// Example 18

Interface MinMax > {
T min ();
T max ();
}
// Now, implement MinMax
Class MyClass > Implements MinMax {
T [] vals;
MyClass (T [] o) {vals = o ;}
// Return the minimum value in vals.
Public T min (){
T v = vals [0];
For (int I = 1; I <vals. length; I ++)
If (vals . CompareTo (v) <0) v = vals;
Return v;
}
// Return the maximum value in vals.
Public T max (){
T v = vals [0];
For (int I = 1; I <vals. length; I ++)
If (vals. CompareTo (v)> 0) v = vals;
Return v;
}
}
Public class GenIFDemo {
Public static void main (String args []) {
Integer inums [] = {3, 6, 2, 8, 6 };
Character chs [] = {'B', 'R', 'P', 'w '};
MyClass Iob = new MyClass (Inums );
MyClass Cob = new MyClass (Chs );
System. out. println ("Max value in inums:" + iob. max ());
System. out. println ("Min value in inums:" + iob. min ());
System. out. println ("Max value in chs:" + cob. max ());
System. out. println ("Min value in chs:" + cob. min ());
}
}



9. Generics of Exception
// Example 20

Interface Executor {
Void execute () throws E;
}

Public class GenericExceptionTest {
Public static void main (String args []) {
Try {
Executor E =
New Executor (){
Public void execute () throws IOException
{
// Code here that may throw
// IOException or a subtype
// IOException
}
};

E.exe cute ();
} Catch (IOException ioe ){
System. out. println ("IOException:" + ioe );
Ioe. printStackTrace ();
}
}
}
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.