Marquake
Marquake

Reputation: 191

How to read this: public <T> T[] toArray(T[] array);

I had read documentation about generics types and I know use it but I have a problem "reading" two methods.

I use "toArray()" and I use "asList()" but I don't understand how write the method solving types.

Example 1

public Iterator<E> iterator();
public Iterator<String> iterator();

Example 2

public E get(int location);
public String get(int location);

Example 3(Here is that I don't understand)

public static <T> List<T> asList(T... array) {
    return new ArrayList<T>(array);
}
public static <String> List<String> asList(String... array) {
    return new ArrayList<String>(array);
}

[modifiers]    [return type]   [¿What is this?]        [type param]
public static    <String>       List<String>      asList(String... array) {

                         v[type param for returned ArrayList]
    return new ArrayList<String>(array);
}

Example 4(the same that Example 3)

public <T> T[] toArray(T[] array);

[modifier]    [return type]  [what is this?]         [param type]
public       <String>        String[]        toArray(String[] array);

¿Is this a return type?

 <String> List<String>

I had read the forum but I don't find some that explain this. All responses are explanations of how to use it but I know how to use it.

Thanks in advance!

===================== EDIT 1 =============================

I have a test:

import java.util.List;

public class ClassTest {

    public static void main(String[] args) {
        ClassTest.testClass(new String[]{"1","2","3"});
    }

    public static <String> List<String> testClass(String[] array){
        System.out.println("** public static <String> List<String> testClass(String[] array){");
       return null;
   }

   public static          List<String> testClass(String[] array){
       System.out.println("** public static          List<String> testClass(String[] array){");
        return null;
   }

}

If I execute the test I have this trace:

** public static          List<String> testClass(String[] array){

If I delete the second method I have this trace:

** public static <String> List<String> testClass(String[] array){

In both case, it works.

Maybe is not the same that my first question but I think so.

The compiler think that the methods are diferent from the other because if y delete

<String>

in the first method compiler says that the method is repeat.

I can't appreciate your response.

===================== EDIT 2 =============================

I have some new information... In Oracle doc exist this:

https://docs.oracle.com/javase/tutorial/java/generics/methods.html

https://docs.oracle.com/javase/tutorial/java/generics/genTypeInference.html

Exactly, what I ask is called: Type Inference(I don't know, at the moment...) related with "Generic Methods".

At present, I'm reading this documentation...

I will be back when I read it.

Thanks for all!

PD: I don't forget completly this thread because maybe I come back to ask.

===================== EDIT 3 =============================

I've read the Oracle's documentation and I think I understand it a little bit more.

I think this is the best way to understand it...

In a class you can define a dynamic type so,

public class Box<T>
    

The same way to do this in a method is like this:

public <U> void test()

The different between this is the place of the "Type Parameter", but in general, is the same.

Correct me if I'm wrong, please.

Next step... A little bit more complicate:

public class Box<T> {
    private T variable;
    ....

    public <U> void test(){
        U variable = null;
        ...
    

One thing that confused me, is that I never used a parameterised method, only like this:

public class Box<T> {
    private T variable;

    public void test(T variable){
        ...

On this way I never needed to use in a method.

Now something more complicate. I don't understand why this below code works. Is a very strange example, I know, but is because I can't see it.

public class TestBox<Mike> {

    public static void main(String[] args) {
        TestBox<Charles> xb = new TestBox();
    }

    public static <Peter> void get(TestBox u){
    }

}

This words, every time are... ¿¿suggestions?? I don't have any class call "Mike" or "Peter"
<Mike> <Peter>

The previous code compile if I left . I guess that is because If I put something between <> might be a real type.

Then I need to confirm, that the word after static(or public if isn't a static method) is just a "SUGGESTION".

Thanks!!

===================== EDIT 4 =============================

New Question related with previos doubt.

public <String> void testClass(String[] array){
    System.out.println("** public <String> void testClass(String[] array){");
}

public           void testClass(String[] array){
    System.out.println("** public        void testClass(String[] array){");
}

Why if I change in the first Method the word String for Integer, I have error...? Integer is "WhatEverIWant"

public <Integer> void testClass(String[] array){
    System.out.println("** public <Integer> void testClass(String[] array){");
}

And Why if I change the parameter String[] for Integer[], it works again?

public <Integer> void testClass(Integer[] array){
    System.out.println("** public <Integer> void testClass(String[] array){");
}

I think is ilogical, respect before comments, Ufff...

Upvotes: 2

Views: 2433

Answers (2)

magooup
magooup

Reputation: 134

If you edit your test code in a IDE like 'idea' or others, you will see the color of 'String' is different between first method and second. That means the compiler treat the first 'String' not 'java.lang.String'. It is just a word like T,E or any other word.I think maybe Java should let compiler check the generic type word to avoid confused with Java's keywords.

Upvotes: 1

Eran
Eran

Reputation: 394146

<T> is not a return type, it's a declaration of generic type parameter T, and it may appear before the return type.

In public <T> T[] toArray(T[] array)

T[] is the return type, and it means that toArray accepts a generic array and returns a generic array of the same type.

In <String> List<String> toArray(String[] array), <String> is a generic type parameter (List<String> is the return type), which is confusing, since it hides the java.lang.String class. It's completely equivalent to <T> List<T> toArray(T[] array).

EDIT:

public static List<String> testClass(String[] array)

is a method that accepts a String array (i.e. an array whose element type is java.lang.String) and returns a List of Strings.

public static <String> List<String> testClass(String[] array)

is a method that accepts an array of some reference type (it has a generic type parameter called String, which has no relation to java.lang.String) and returns a List of the same type.

The two methods have a different argument, even though it looks like they don't.

When you call testClass with a String[] argument, the non-generic method that accepts a String array will be called, since its arguments are a better fit to the array you are passing than the generic method. If you remove the non-generic method, the generic method is called instead, since the generic method accepts any non-primitive array.

Maybe it will help you better understand if you try to call the method with different types of arrays :

String[] strarray = {"a","b"};
testClass(strarray); // calls the first (non generic) method
Integer[] intarray = {1,2,3,4};
testClass(intarray); // calls the second (generic) method

Upvotes: 5

Related Questions