0
class jj<T> {
T ob;
jj(T ob) {
    this.ob = ob;
}

void show() {
    System.out.println(ob);
}}
class demo {
public static void main(String[] args) {
    // jj<Integer>[] lol=new jj<Integer>[10];// Not Allowed
    jj<Integer>[] lol = new jj[10];//But this is allowed why?
    for (int i = 0; i < 10; ++i)
        lol[i] = new jj<>(i * 10);

    for (jj<Integer> x : lol)
        x.show();

}

Why the above code is allowed if generics arrays are not allowed in java? plz help!

  • 1
    Allowed, yes, but the compiler is going to give you a warning that you should respect. – azurefrog Oct 20 '17 at 20:44
  • Thanks but can u elaborate? i mean jj[] lol=new jj[10]; is not allowed in java but jj[] lol = new jj[10]; is allowed why?(what is happening in background) and compiler gives no warning. – Jagjot Singh Oct 20 '17 at 20:47
  • Oracle JDK 8u131 gives me a warning on compile of the code: `Note: GenericArrays.java uses unchecked or unsafe operations.` `Note: Recompile with -Xlint:unchecked for details.`. Compiling with `-Xlint:unchecked` gives `GenericArrays.java:6: warning: [unchecked] unchecked conversion` `jj[] lol = new jj[10];// But this is allowed why?` with `new` underlined. As does my Eclipse Neon.1 install using the same JDK: `Type safety: The expression of type jj[] needs unchecked conversion to conform to jj[]`. Perhaps some warnings are turned off in your compiler (+ possible IDE) setup? – Mark A. Fitzgerald Oct 20 '17 at 20:53
  • Just as a note, please stick to naming conventions. Class names should start with an upper-case letter (camelcase). Methods and variables with a lower-case letter. – Zabuzard Oct 20 '17 at 21:04

2 Answers2

2

The code is allowed because new jj[10] is not a generic array (e.g. new T[10]), but is instead an array of raw jj instances - jj with its generic arguments omitted. new jj[10] creates a new array of raw jj, not a new array of jj<Integer>. Java allows one to force instances of a raw type to be assigned to a reference of type with generic arguments as the code does with jj<Integer>[] lol = new jj[10];. I believe this is there for backwards compatibility with pre-Java 5 code.

Mark A. Fitzgerald
  • 1,164
  • 1
  • 8
  • 19
2

Generic arrays are allowed. The compiler is going to give you a warning because the generics implement type erasure meaning that they do not exist at run time. The compiler will give you a warning when creating a generic reference, and for the object's type you need to have a object array that is casted.

CAN'T do this:

//SYNTAX ERROR
jj = new T[10];

But CAN do this:

//This suppresses the unchecked-cast warning that the compiler will give
@SuppressWarnings("unchecked") 
//Can't create a generic array but can create an Object array and cast it to be a //compatible type
T[] jj = (T[])new Object[10];

However in the code above is not creating a generic array, instead it is creating an array of the class jj that has a generic in it.

webDev
  • 3,868
  • 1
  • 17
  • 40