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!

4
  • 1
    Allowed, yes, but the compiler is going to give you a warning that you should respect. Commented Oct 20, 2017 at 20:44
  • Thanks but can u elaborate? i mean jj<Integer>[] lol=new jj<Integer>[10]; is not allowed in java but jj<Integer>[] lol = new jj[10]; is allowed why?(what is happening in background) and compiler gives no warning. Commented Oct 20, 2017 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<Integer>[] 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<Integer>[]. Perhaps some warnings are turned off in your compiler (+ possible IDE) setup? Commented Oct 20, 2017 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. Commented Oct 20, 2017 at 21:04

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

"backwards compatibility with pre-Java 5 code" - yeah, it is called raw-type and should not be used since it has no advantages compared to jj<Object> which should be used instead (if one truly wants to allow all objects).
Raw types! Yes, that's the term I was looking for. Answer updated accordingly. Thanks, @Zabuza.
You've welcome, @JagjotSingh. :) Glad to help.
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.

1 Comment

Also it is better convention to use the generic name E[] instead of T[] for a collection of items.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.