Java Design Patterns-factory methods & Template Methods

Source: Internet
Author: User

Java generics have always been a part of my interest, but since I'm talking about generics, I have to mention erasing. Java generics are implemented using erase, and when generics are used, the specific type information is "erased". For example,:list<string> and list<integer> are essentially the same type at run time, and are erased to the "native" type, which is List.

The generic type parameter will erase to its first boundary, such as list<t> will be erased to list, while the normal type variable is erased to object without specifying a boundary.

1  PackageCom.test.generic;2 3  Public classErased<t> {4     Private Final intSIZE = 100;5      Public Static voidf (Object Arg) {6         if(ARGinstanceofT) {}//Compile Error7T var =NewT ();//Compile Error8t[] Array =NewT[size];//Compile Error9t[] Array =NewOnject[size];//Compile ErrorTen     } One}
View Code

Factory method

In the above code, the creation of a new T () operation cannot be implemented, partly because of the erasure, because the compiler cannot verify that the code T has a default (no parameter) constructor. The solution for Java is to pass a factory object and use it to create a new instance. The most convenient factory object is the class object, as shown in the following code:

1  PackageCom.test.generic;2 3 classClassasfactory<t> {4 T x;5      PublicClassasfactory (class<t>kind) {6         Try {7x =kind.newinstance ();8}Catch(Exception e) {9             Throw NewRuntimeException (e);Ten         } One     } A } -  - classEmployee {} the  -  Public classInstantiategenerictype { -  -      Public Static voidMain (string[] args) { +classasfactory<employee> FE =NewClassasfactory<employee> (Employee.class); -System.out.println ("Classasfactory<employee> succeeded"); +          A         Try { atclassasfactory<integer> fi =NewClassasfactory<integer> (Integer.class); -}Catch(Exception e) { -System.out.println ("Classasfactory<employee> failed"); -         } -     } -  in}
View Code

The operation results are as follows

As seen from the running results, it can be compiled, but it will fail because of classasfactory<integer> because the integer does not have any default constructors. Because this error is not captured at compile time. Sun recommends using an explicit factory and restricting the type to accept only the classes that implement the factory, as shown in the following code:

1  PackageCom.test.generic;2 3 InterfaceFactoryi<t> {4 T Create ();5 }6 7 classFoo2<t> {8     PrivateT x;9      Public<fextendsFactoryi<t>>Foo2 (F factory) {Tenx =factory.create (); One     } A } -  - classIntegerfactoryImplementsFactoryi<integer> { the      PublicInteger Create () { -         return NewInteger (0); -     } - } +  - classWidget { +      Public Static classFactoryImplementsFactoryi<widget> { A @Override at          PublicWidget Create () { -             return Newwidgets (); -         } -     } - } -  Public classFactoryconstraint { in      Public Static voidMain (string[] args) { -         NewFoo2<integer> (Newintegerfactory ()); to         NewFoo2<widget> (Newwidget.factory ()); +     } -}
View Code

Class<t> happens to be creating a built-in factory object, and you can get a compile-time check by creating a factory object as shown above.

Template method:

Another way is to use the template method design pattern, by implementing abstract class (template) abstract method to create objects, also can get compile time type check, the following is the code:

1  PackageCom.test.generic;2 3 Abstract classGenericwithcreate<t> {4     FinalT element;5 genericwithcreate () {6element =Create ();7     }8     AbstractT Create ();9 }Ten  One classX {} A  - classCreatorextendsGenericwithcreate<x> { - @Override the X Create () { -         return NewX (); -     } -     voidf () { + System.out.println (Element.getclass (). Getsimplename ()); -     } + } A  Public classCreatorgeneric { at      Public Static voidMain (string[] args) { -Creator C =NewCreator (); - c.f (); -     } -}
View Code

Summarize:

In the process of using generics, any operation that needs to know the exact type of information at run time cannot work properly because of the erasure. By reflecting the use of a factory method or a template method, we can know whether the type of arguments passed when the object was created is correct in the compiler.

Java Design Patterns-factory methods & Template Methods

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.