Generic Learning Record 1

Source: Internet
Author: User

Recently in the study of generics, when using generics there are 3 things you can't do: one cannot use instanceof, two cannot be a new object, and three cannot create a generic array. I would like to record my understanding of these 3 points, especially the 3rd.

Cannot use instanceof

I think this is a good understanding, because the reason for erasing, generics will be erased to the type upper limit. There is no point in using instanceof in this case, because you do not know the actual type of T. This means that when a generic is passed in a parameter, the editor checks the type, guarantees the type is correct, and enforces the transformation when the value is assigned. In other places, T will become its type upper limit, if not write the type upper limit, that is object, so the use of instanceof is useless.

The compiler's explanation is clear that the type information is erased at run time. The solution is to use the type upper limit of t instead of T, and this is object.

Cannot create object

You can declare references with generics, but you cannot use generics to create objects. The reason is because you can't guarantee that T must have the construction method you wrote. such as t t = new T () you are not guaranteed to pass in the specific type information of the class when there is no parameter to construct the method.

The workaround is to return the object through the method, and then complete the method in the class that specifically knows the type information.

1  Public Abstract classTest<t> {2 T T;3     4      PublicTest () {5t =Create ();6     }7     8     AbstractT Create ();9 }Ten  One classTest_1extendsTest<string>{ A @Override - String Create () { -         return""; the     } -      -}

In a nutshell, the time to create a generic object is deferred until you can determine the type of the parameter.

Cannot create a generic array

Why can't I create a generic array?

1  Public classGenericarraytest<t> {2 T T;3      PublicT Get () {4         returnT;5     }6      Public voidTest () {7genericarraytest<string>[] arr =NewGenericarraytest<string>[10];8     }9}

As in the above code, because the type erase after this object array contains the native Genericarraytest object, T is the object type of,genericarraytest<string> and genericarraytest< Integer> is the same, then if there is obejct[] Objarr This reference, it can be assigned to arr, but you cannot guarantee that Objarr will not store genericarraytest<integer> objects. The result is that ARR will have genericarraytest<string> and genericarraytest<integer> in this array. Then you get the genericarraytest element in the ARR array, and then the object of type T, the object of string, the compiler will help you to force the transformation. It means that arr[0].get () returns a String type object instead of a, because the compiler helped you transform it. However, because there may be genericarraytest<integer> in arr, getting an array element and then calling the Get method returns an Integer object that is coerced into a string to error. Therefore, you cannot create a generic array.

Is that it?

And yet there is no. Generics and arrays are paired together with some particularly confusing places. I would like to give an example of the problem I have seen on csdn, and I am not particularly satisfied with the answer. I want to talk about my understanding.

1  Public classSimplecollection<t> {2      Public Static voidMain (string[] args) {3     //object[] o = new OBJECT[10];4     //string[] s = (string[]) o;//Run Error: Exception in thread "main"5                                     //java.lang.ClassCastException:6                                     //[Ljava.lang.Object; cannot is cast to7                                     //[Ljava.lang.String;8Simplecollection<string> si =NewSimplecollection<string>();9 Si.method ();Ten  One     } A      Public voidmethod () { -object[] o =NewObject[10]; -T[] t = (t[]) o;//Type safety:unchecked cast from object[] compile warning, run normally the     } -  -}

The question of the questioner is for the 4th line error, and the use of generics, call method does not error.

That's what I understand:

First, why did the four error? This is a transformation problem, the parent class reference if you point to a parent class object, then it is not wrong to force the transformation to compile, but it will be reported classcastexception when executed. If the parent reference refers to a subclass object, then the transition is fine. So

object[] o = new STRING[10];
String[] s = (string[]) o;

This is a good use of error.

So why use generics without an error? Because of the type erasure. T will be erased as object. So 13, 14 lines equals

object[] o = new STRING[10];
object[] t = o;

Could this run be an error? Obviously not.

Does that mean you can use generics to help transform arrays?

Obviously not, I think there is little impact in this case with generics, or the advantage of generics.

Let's revise this example.

1  Public classSimplecollection<t> {2      Public Static voidMain (string[] args) {3         //object[] o = new OBJECT[10];4         //string[] s = (string[]) o;//Run Error: Exception in thread "main"5                                     //java.lang.ClassCastException:6                                     //[Ljava.lang.Object; cannot is cast to7                                     //[Ljava.lang.String;8Simplecollection<string> si =NewSimplecollection<string>();9 Si.method ();Tenstring[] arr =si.method2 (); One  A     } -      Public voidmethod () { -object[] o =NewObject[10]; theT[] t = (t[]) o;//Type safety:unchecked cast from object[] compile warning, run normally -     } -  -      Publict[] Method2 () { +object[] o =NewObject[10]; -T[] t = (t[]) o; +         returnT; A     } at}

Now we have added a method2 method. The advantage of using generics is that the compiler will help us transform, without having to transform ourselves, and ensure that the type is correct.

There are no errors in compiling here, but the 10th line is an error. The reason and the fourth line of direct transformation are the same. So be especially careful with generic assignments and errors when passing in parameters. Method () There is no error just because there is no assignment, there is no transformation. Does not mean that a generic can be used to transform an array in a safe form.

What else is worth saying

There are some small details worth saying, not about generics, but about arrays, which I found when testing small examples. I think it's interesting and worth mentioning.

String[] and object[] in the end is not the relationship between the father and son class?

I feel the answer is both and not.

Yes: That's because new string[2] instanceof object[] returns True

No: That is because String[].class.getsuperclass () is returning java.lang.Object, and Object[].class is [Ljava.lang.Object; from this point of view it seems that they are not related.

It's really a bit confusing.

Generic Learning Record 1

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.