java Generic Parsing (04): Constraints and limitations In the first two sections, recognizing and learning about generics and wildcard characters, beginners may need some time to realize the benefits and power of generic programming, especially when they want to be a library programmer, and the application programmer needs to know how to use generics, Here is an introductory explanation of the constraints and limitations of generics usage.
type parameters cannot be instantiated with a base typeIt 's good to understand that when you instantiate a generic class, generic parameters cannot use basic types, such as list<int>, which is illegal, and to store the base type you can take advantage of the basic type of wrapper classes such as List<integer>, list<double > and so on, add the following eight basic types corresponding to the wrapper class, and the default initial value
[CODE01]:
BYTE byte 0 short short 0 int Integer 0 long long 0L float FLoat 0.0F double double 0.0D char Character ' \u0000 ' boolean Boolean False
cannot instantiate type parametercreating objects in Java uses the new keyword, but generic type parameters cannot be used for instantiating objects, such as:
[CODE02]
Public Couple () {wife = new T (); husband = new T ();}//Error
If you want to create a T object, you must use Java reflection to create the object, unfortunately T.
class is also not supported in Java, so a way to compensate is to pass in a class object that is described as T, such as Class<t>
[CODE03]
public static <T> couple<t> CreateInstance (class<t> clazz) { try { return new couple<t > (Clazz.newinstance (), clazz.newinstance ()); } catch (Exception e) { return null; } }
Beginners are unfamiliar with Java reflection do not worry, as long as you know that you cannot instantiate a type parameter, in the same vein, you cannot instantiate a generic array, such as
[CODE04]
public static <T> t[] Maxtwo (t[] values) {t[] array = new t[2];}//Error
It is not legal to build an array of generics, because this construct is always constructed after erasing , which is the
new Object[2], which is not the result we want. And this can cause some run-time errors. To further illustrate the hidden problem, take a look at the following code: [Code05]
public static <t extends comparable<t>> t[] Maxtwo (t[] array) { object[] result = new Object[2]; Return (t[]) result; Type safety:unchecked cast from object[] to t[] }
This method produces a variation warning: object[] is not checked for conversion to t[]. Let's try this call:
maxtwo(
Newstring[] { "5","7","9"}); After running, a type conversion exception occurs because the method converts object[] to string[] at the time of the call, and the type conversion fails. How to solve it? Also here you can use Java launch to solve: [CODE06]
public static <t extends comparable<t>> t[] Maxtwo (t[] array) { //Type safety:unchecked cast from Object [] to t[] return (t[]) array.newinstance (Array.getclass (). Getcomponenttype (), 2); }
Unable to declare parameterized array couple<employee>[] Couple =
new couple<employee>[5] ; This declarative is not legal, there is a problem or through the type erase mechanism to explain, type erasure after the type of couple is couple[], consider the two ways of assignment: 1.couple[0] = "Wife", the compiler will error, this is a very obvious mistake, couple each element is a couple type. 2.couple[0] = new couple<string> (), type erase after this can be detected by the array, but still the wrong type, because couple is defined at the time of declaration is couple< Employee>, so there is a problem. If you want to hold a collection of parameterized type objects, consider using arraylist<couple<employee>> to declare them, and in Java it is recommended that you take precedence over collections, which is both safe and efficient.
type parameter cannot be queried for typeUsually we will use
if (arg1
instanceof Couple)
To determine whether Arg1 belongs to the couple type, some think-of programmers may want to be more specific about the arg1 type is couple<t>, specifying type parameters such as:
[Code07]
if (arg1 instanceof couple<employee>) {...}//Error
There is no generic concept in a Java virtual machine, and all
instanceof type queries query only the original type, so the syntax in CODE07 is not supported in Java. Similarly, it is not allowed to specify type parameters in coercion type conversions, such as:couple<employee> Couple = (couple<employee>) arg1; //Error
cannot throw, cannot capture generic class instancesin Java, public
class genericexception <T>
extends Exception {... this generic class extension sub-throwable is not legal and cannot be passed through the compiler. You cannot use a type parameter in a catch clause, such as:
[Code08]
public static <t extends throwable> void dosomething (class<t> T) { try { //do something ... } CATC H (T e) { e.printstacktrace (); } } Error
The code in CODE08 is not legal, and it is legal to use the type parameter in the exception declaration, for example:
[Code09]
public static <t extends throwable> void dosomething (T-t) throws T { try { //do something ... } catch (t Hrowable e) { e.printstacktrace (); throw t; } } That's right
type parameters in a generic class cannot be used in a static contextHow do you understand this? See an example of this, such as a generic single example: [Code10]
public class Singleton <t>{ private static T instance; public static T getinstance () {..}}
The above code, is not through the compiler, how to explain this? Imagine that this program can run, declare a singleton<string> and a singleton<employee>, and the type erase is singleton, but contains only one instance domain, This field can not be both string type and employee type, so the hypothesis is not established, by the way review the school learning of the absurdity ~ ~
conflicts caused by type erasurelook at a generic class:
[Code11]
public class Nameclash<t> {public Boolean equals (T value) { return false; } }
from the definition of this class, there are two equals methods, one defined by itself
Public
Boolean equals (T value) {...} , one is inherited from Object
Public
Boolean equals (Object obj) {...}, but after the type erasure, the former method becomes
Public
Boolean equals (Object value) {...}, and it is not possible to have two method names and parameters in a class, so the conflicts that arise here are not available through the compiler. Corrections can be made by renaming the method. Erase-induced conflicts are also reflected in another point, and then look at the wrong code:
[Code12]
Class Calendar implements Comparable<calendar> {...} Class GregorianCalendar extends Calendar implements comparable<gregoriancalendar> {...}
The above code is illegal, why? After reviewing the type erase, the virtual opportunity is
calendar Class Synthesis Bridge method, implemented Comparable<calendar> Get a bridge method: public
int compareTo {
return compareTo Span style= "font-size:14pt" ((Calendar) o);} implemented COMPARABLE< gregoriancalendar &NBSP; > after type erasure, the virtual machine is GregorianCalendar synthesizing A bridge method: public
int compareTo {
return compareTo Span style= "font-size:14pt" (( gregoriancalendar &NBSP; ) o);} This way there are two identical methods in the GregorianCalendar class, which is not allowed.
Java Generic Parsing (01): Understanding Generics
Java Generic Parsing (02): Wildcard Qualifier
Java Generic Parsing (03): Virtual machine execution Generic code java Generic Parsing (04): Constraints and limitations
===== "Thanks to the pro-reading of the article, if the pro feel this article is helpful,
Top One topChant
,Pro-Support will give me the impetus to move forward. "=====
Java Generic Parsing (04): Constraints and limitations