1

I hava some problems with my code. First of all I have an interface:

public interface Generator <T, R> {
    public T next (R x);
}

Then, I have created the class "DemoClass"

public class DemoClass {
    private int id;

    public DemoClass (int id){
        this.id = id;
    }
}

And... Generic Class as well

public class GenericClass implements Generator <DemoClass, Integer> {
    public DemoClass next(Integer x) {
        return new DemoClass (x);
    }
}

After, I have created Main Class and a generic static method that containts a method like Class . I would like to know, is there any opportunity to use such construction like Class ??? My MainClass

import java.util.*;

public class MainClass {
    private static Random rand = new Random ();

    public static <T> T [] arr (T [] a, Class <?> typeToken){
        try{
            Generator <?, ?> gen = (Generator <?, ?>)typeToken.newInstance(); // How can I pass two paramets to Generator <?, ?>???
            for (int i=0; i!=a.length; i++){
                a[i] = (T) gen.next(rand.nextInt(100)); // This  line does not work!
            }
        } catch (Exception e){
            throw new RuntimeException (e);
        }
        return a;
}

    public static void main (String [] args){
        DemoClass [] myarr = arr (new DemoClass[10], GenericClass.class);
    }
}
Suraj Rao
  • 29,388
  • 11
  • 94
  • 103

2 Answers2

0

If you want to make that line work, you could do this:

public static <T> T[] arr(T[] a, Class<? extends Generator<T, Integer>> typeToken) {
    try {
        Generator<T, Integer> gen = typeToken.newInstance();
        for (int i = 0; i != a.length; i++) {
            a[i] = gen.next(rand.nextInt(100));
        }
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    return a;
}

Basically, the bound on Class makes it so that what is returned by newInstance is a Generator<T, Integer>.

How can I pass two paramets to Generator ???

There is no need to pass any type parameters. Since Java generics use erasure, the concrete generic type arguments are not needed at runtime.


If you are using Java 8, I would suggest using a Supplier instead of a Class, since it allows you to create an instance without having to deal with the exceptions:

public static <T> T[] arr(T[] a, Supplier<? extends Generator<T, Integer>> typeToken) {
    Generator<T, Integer> gen = typeToken.get();
    for (int i = 0; i != a.length; i++) {
        a[i] = gen.next(rand.nextInt(100));
    }
    return a;
}

...

// passing reference to constructor of GenericClass
DemoClass[] myarr = arr(new DemoClass[10], GenericClass::new);
Jorn Vernee
  • 31,735
  • 4
  • 76
  • 93
-1

No.

Generics work at compile time only. At runtime, all of the instances of class are exactly the same, the information of the parametrized types gone.

This is known as type erasure and it was designed that way to ensure that Java 1.4 binaries were compatible with Java 5 VM.

You can get a lot of info about this by searching "type erasure java" in the search box; for example Avoiding Java Type Erasure

SJuan76
  • 24,532
  • 6
  • 47
  • 87