participate


Generics - Clarification for Array Types and generics
<<   Back to Forum  |   Give us Feedback
This topic has 20 replies on 2 pages.    1 | 2 | Next »
oliviert
Posts:18
Registered: 9/24/97
Clarification for Array Types and generics   
Oct 22, 2003 1:22 PM

 
Hi,

The following construct doesn't seem to be legal:
List<String>[].class
or
List<String>.class

But this doesn't seem to be illegal considering the specs. A legal PrimaryNoNewArray is: Type.class and Type can be a ReferenceType that could potentially be a generic type.

Maybe I missed something, but I don't think the specs are clear on this construct. The early access compiler rejects it.

The specs I read should allow array types. Page 12 gives examples with array of generic types.

I tried to compile this example, but all usage of arrays of generic types are rejected.

import java.util.*;

public class X {
void foo() {
List<String>[] array = null;
System.out.println(array.getClass());
}

public Object get(Class<?>[] params) {
Object o = new Vector<String>[3];
}
}

Thanks for clarifying this point.
 
gafter
Posts:669
Registered: 6/25/98
Re: Clarification for Array Types and generics   
Oct 22, 2003 1:51 PM (reply 1 of 20)  (In reply to original post )

 
Arrays of generic types are not allowed because they're not sound. The problem is due to the interaction of Java arrays, which are not statically sound but are dynamically checked, with generics, which are statically sound and not dynamically checked. Here is how you could exploit the loophole:
class Box<T> {
    final T x;
    Box(T x) {
        this.x = x;
    }
}
 
class Loophole {
    public static void main(String[] args) {
        Box<String>[] bsa = new Box<String>[3];
        Object[] oa = bsa;
        oa[0] = new Box<Integer>(3); // error not caught by array store check
        String s = bsa[0].x; // BOOM!
    }
}

We had proposed to resolve this problem using statically safe arrays (aka Variance) bute that was rejected for Tiger.
 
rreyelts
Posts:568
Registered: 11/12/97
Re: Clarification for Array Types and generics   
Oct 22, 2003 1:53 PM (reply 2 of 20)  (In reply to original post )

 
The spec is out of date. I believe that Neal is supposed to be including an updated spec with the next release. You might want to read an article that Angelika Langer posted a while back on the problems with arrays and generics by type erasure:

http://www.langer.camelot.de/Articles/Java/JavaGenerics/ArraysInJavaGenerics.htm

God bless,
-Toby Reyelts
 
oliviert
Posts:18
Registered: 9/24/97
Re: Clarification for Array Types and generics   
Oct 22, 2003 2:32 PM (reply 3 of 20)  (In reply to #2 )

 
So my next question is: When will we get an updated spec?
I'd like to know what is legal and what is not. If I cannot rely on the specs, I don't know what I should do.

For now can I assume that any construct with array of generics is illegal and can safely be rejected as parse time?

Thanks.
 
gafter
Posts:669
Registered: 6/25/98
Re: Clarification for Array Types and generics   
Oct 22, 2003 2:42 PM (reply 4 of 20)  (In reply to #3 )

 
For now can I assume that any construct with array of
generics is illegal and can safely be rejected as
parse time?

Yes, with the exception of
   Whatever<?>[]

which is safe and allowed, but not in the current prototype.

I don't think I will be able to provide a much more up-to-date spec with this month's prototype.
 
spf1
Posts:7
Registered: 6/12/98
Re: Clarification for Array Types and generics   
Oct 22, 2003 2:51 PM (reply 5 of 20)  (In reply to #4 )

 
It worries me that I'm going to have to keep in the back of my mind the rule "Don't store generic types in arrays". It adds complexity to the language, having this extra rule to remember. I understand that this is the best solution that can be put together given the release schedule. However, are there better solutions in the works for later releases? Or is this rule to remain in Java from here on out?
 
oliviert
Posts:18
Registered: 9/24/97
Re: Clarification for Array Types and generics   
Oct 22, 2003 3:00 PM (reply 6 of 20)  (In reply to #4 )

 
And what about the class literal and generic array types?
Is the syntax T[].class legal when T is a generic type?

Thanks for your answers.
 
gafter
Posts:669
Registered: 6/25/98
Re: Clarification for Array Types and generics   
Oct 22, 2003 4:23 PM (reply 7 of 20)  (In reply to #5 )

 
We're looking at possible changes for 1.6 or 1.7. Don't know what will become of it.
 
snol
Posts:5
Registered: 8/30/03
Re: Clarification for Array Types and generics   
Oct 22, 2003 6:16 PM (reply 8 of 20)  (In reply to #1 )

 
At this point you can still work around the limitations like this, leading to a ClassCastException. Is this just as bad a situation as the other loophole was? Cause just having a ClassCastException thrown seems like an okay consequence to me.

class Array<T> {
    T[] array;
    Array(int sz) {
        array = (T[])(new Object[sz]);
    }
    void set(int i, T elt) {
        array[i]=elt;
    }
    T get(int i) {
        return array[i];
    }    
}
 
class Loophole {
    public static void main(String[] args) {
        Array<Box<String>> bsa = new Array<Box<String>>(3);
        Object[] oa = bsa.array;
        oa[0] = new Box<Integer>(3); 
        String s = bsa.get(0).x;     // ClassCastException
    }
}


Another weird thing is that ClassCastExceptions are also thrown whenever you try and modify the array member variable from outside the Array class: for instance
Box<String> bs = bsa.array[0]
and
bsa.array[0] = new Box<String>("Hello")
both throw ClassCastExceptions, whereas the get and set methods, which ostensibly do the same things, work fine. Personally I'm OK with it as long as there is a way of making arrays of generic types; of course it'd be nice if we didn't have to use workarounds like these.
 
oliviert
Posts:18
Registered: 9/24/97
Re: Clarification for Array Types and generics   
Oct 22, 2003 6:31 PM (reply 9 of 20)  (In reply to #7 )

 
Could you please tell me if this bug 4881265 means that T.class is illegal when T is a generic type? Is it possible to write T<?>[].class ?

This is my understanding of the evaluation of this bug.

Thanks for the clarification.
 
rreyelts
Posts:568
Registered: 11/12/97
Re: Clarification for Array Types and generics   
Oct 22, 2003 8:41 PM (reply 10 of 20)  (In reply to #8 )

 
It seems like the problem should be here
array = (T[])(new Object[sz]);
I don't know why the compiler doesn't give you a warning there. It shouldn't think that it is safe to cast to a T[].

The client code fails with a ClassCastException, because that is where the casts for T are generated. That is how erasure works - it can't generate casts in the "generic class", because it wouldn't know what to cast to. So, casts generate them in the client code. Casts in the source code of your generic class (i.e. ( T[] )) just get thrown away.

God bless,
-Toby Reyelts
 
snol
Posts:5
Registered: 8/30/03
Re: Clarification for Array Types and generics   
Oct 22, 2003 11:44 PM (reply 11 of 20)  (In reply to #10 )

 
It seems that in the case of the Array<T> class above the array member is seen after erasure as being of type Object and not an array type at all; the compiler must be inserting some complicated casting within the class for the get and set methods, since the only way I can get direct indexing to function outside is something like
Array<String> stringa = new Array<String>(3);
((Object[])(stringa.array))[0]=(Object)"hello";
String c = (String)((Object[])(stringa.array))[0];
... Of course, given this as the alternative option I'll stick with using get and set methods. Is there some reason why erasure changes the type T[] to Object rather than Object[]?
 
snol
Posts:5
Registered: 8/30/03
Re: Clarification for Array Types and generics   
Oct 22, 2003 11:56 PM (reply 12 of 20)  (In reply to #11 )

 
erasure changes the type T[] to Object rather than Object[]
- ok I'm wrong; javac -s makes everything clear. Sorry for the misinformative previous post.
 
xuhaoqing
Posts:49
Registered: 7/15/01
Re: Clarification for Array Types and generics   
Oct 23, 2003 6:20 AM (reply 13 of 20)  (In reply to #1 )

 
class Box<T> {    
    final T x;
    Box(T x) {
        this.x = x;
    }
}
class Loophole {
    public static void main(String[] args) {
        Box<String>[] bsa = new Box<String>[3];
        Object[] oa = bsa;
        oa[0] = new Box<Integer>(3); // error not caught by array store check
        String s = bsa[0].x; // BOOM!    
    }
}


Seems the root cause is the Runtime knows nothing about generics.

Couldn't Java make Runtime be aware of generics and do not break backward compatibility?

e.g. make Vector<String>.class not equal Vector.class, Vector<Object>.class equal Vector.class, etc. So array store error can be caught.
 
oliviert
Posts:18
Registered: 9/24/97
Re: Clarification for Array Types and generics   
Oct 23, 2003 6:24 AM (reply 14 of 20)  (In reply to #12 )

 
I am working on a grammar for the JDK 1.5 and I cannot figure out how I should write this rule to get a LALR(1) grammar.

PrimaryNoNewArray ::= Type '.' 'class'

In this case Type can be a PrimitiveType or a ClassOrInterfaceType or an ArrayType. Which means that it could potentially be an array of generic types.

I simply would like to get the rules in the grammar that involve array types. What is actually legal and what is not?

Thanks.
 
This topic has 20 replies on 2 pages.    1 | 2 | Next »
Back to Forum
 
Read the Developer Forums Code of Conduct

Click to email this message Email this Topic

Edit this Topic
  
 
 
Forums Statistics
    Users Online : 28
  • Guests : 133

About Sun forums
  • Oracle Forums is a large collection of user generated discussions. It is here to help you ask questions, find answers, and participate in discussions.

    Check out our guide on Getting started with Oracle Forums for a full walkthrough of how to best leverage the benefits of this community.

Powered by Jive Forums