PDA

View Full Version : Java: Why isn't this allowed?



Sang-drax
09-07-2005, 03:14 PM
Consider this example of valid code:


class Test<E> {
E[] array;

Test() {
array = (E[]) new Object[100];
}
}

What is the reason that the following isn't allowed?


array = new E[100];


It seems stupid that this isn't allowed because the original code is unelegant and will generate a warning. It is also a needed construction in a lot of containers.
I don't see any reason why the 'new E'-notation shouldn't be allowed. It doesn't create any E objects, so E doesn't have to be a known type.

I've asked my lecturer, but she doesn't have an answer.

Narf
09-07-2005, 05:51 PM
Read section 7.3 in the following tutorial for why this isn't allowed:
http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

Sang-drax
09-08-2005, 09:28 AM
This is what the tutorial says:

Similarly, attempting to create an array object whose element type is a type variable causes a compile-time error:


<T> T[] makeArray(T t) { return new T[100]; // error
}

Since type variables donít exist at run time, there is no way to determine what the actual array type would be.


I don't agree here. Sure, the type T isn't known, but no T object is created, only references (100 of them) to T objects are created (and set to null).

The only thing I ask is that

E[] array = new E[100];
should be interpreted as

E[] array = (E[]) new Object[100];

Narf
09-08-2005, 04:32 PM
I don't agree here.
Feel free to email Sun and ask them to change the language to suit your preferences.

Sang-drax
09-09-2005, 04:58 PM
Feel free to email Sun and ask them to change the language to suit your preferences.
Feel free to not post in this thread unless you have something useful to say.

Narf
09-09-2005, 05:32 PM
Feel free to not post in this thread unless you have something useful to say.
My suggestion was very serious. I'm sorry that you don't approve of reality, but if you don't like it, you can suggest changes to Sun. But thanks for your rude and insulting response anyway. I always appreciate being wrongly flamed by ..............s. :rolleyes:

Zach L.
09-09-2005, 07:33 PM
This went downhill fast.

cboard_member
09-10-2005, 02:26 AM
This went downhill fast.

Yes much faster than one of my threads, I thought I'd be holding the record for longer :(

xErath
09-13-2005, 02:20 PM
That's allowed in C++ because the compiler compiles the templated code for each template instance, and links at the end.
Instead, the Java VM instantiates the templated code at runtime (which is slower) causing that issue.

Sang-drax
09-13-2005, 02:51 PM
But everything works with the cast, which means that the question isn't whether it is possible or not, but rather why they choose not to allow it.

Frobozz
09-13-2005, 03:12 PM
They've given their reason.


Since type variables donít exist at run time, there is no way to determine what the actual array type would be.

If you don't think that is a good enough answer, try asking on the Java forums (http://forums.java.sun.com/)

CornedBee
09-14-2005, 05:16 AM
The only thing I ask is that

E[] array = new E[100];
should be interpreted as

E[] array = (E[]) new Object[100];

But the (E[]) cast is a no-op. E is (unless it's defined as 'extends XXX') completely replaced by Object in the resulting bytecode. All you're doing is casting an object array to an object array. The only effect of generics are the casts the compiler writes into the code automatically.

Allowing "new E[10]" would lead to the misconception that the runtime type of the array would be E[]. It isn't. It's Object[], which cannot be cast to any more specialized array type. For example, this code throws a class cast exception:
String[] bla = (String[]) new Object[10];

On the other hand, this code is valid, the runtime type being String[]:
String[] bla = new String[10];

Allowing this:
E[] bla = new E[10];
would lead people to believe that the runtime type is E[]. This can be dangerous. And that's why it's not allowed.

Sang-drax
09-14-2005, 01:40 PM
The only effect of generics are the casts the compiler writes into the code automatically.
Thanks!

If I were able to write

E[] array = new E[10]it'd be interpreted as
Object[] array = new Object[10];But would this be unsafe? I still cannot do:
Object someObject = ...
array[2] = someObject;

Sang-drax
09-14-2005, 02:24 PM
Hmm, I guess that's why the equals method doesn't work in this case.

import java.io.*;

class Number implements Comparable<Number> {
int n;
Number(int n) {
this.n = n;
}
int get() {
return n;
}
public boolean equals(Number number) {
return n == number.get();
}
public int compareTo(Number number) {
Integer i = new Integer(n);
return i.compareTo(number.get());
}
}

class TestContainer<E extends Comparable<E> > {
TestContainer() {
}
boolean isSame(E e1, E e2) {
return e1.equals(e2);
}
int compare(E e1, E e2) {
return e1.compareTo(e2);
}
}

public class Test {

public static void main(String[] arguments) {
Number n1 = new Number(3);
Number n2 = new Number(3);
Number n3 = new Number(4);
TestContainer<Number> testContainer = new TestContainer<Number>();
//Compare two equal elements
System.out.println(testContainer.isSame(n1,n2));
System.out.println(testContainer.compare(n1,n2));
//Compare two different elements
System.out.println(testContainer.compare(n1,n3));
System.out.println(testContainer.compare(n3,n1));
}

}
I still haven't Java generics 100% figured out.

CornedBee
09-14-2005, 03:28 PM
The equals method is not generic. It always takes an Object parameter.