Aeon,
before you start fumbling with the bytecodes directly, how about
changing your code a little bit? Your version doesn't work with
primitive data types due to the limitation with generic type
parameters, but this slightly changed version works fine:
class Array
{
@SuppressWarnings("unchecked")
static <T> T create(Class<T> type, int length)
{
if(!type.isArray() )
throw new IllegalArgumentException( "Type parameter must contain
the class representation of an array." );
return (T) java.lang.reflect.Array.newInstance
(type.getComponentType(), length);
}
}
public class Main
{
public static void main(String[] args)
{
System.out.println(Array.create(Byte[].class, 10));
System.out.println(Array.create(byte[].class, 10));
System.out.println(Array.create(byte[][].class, 10));
}
}
You simply pass the class representation of a typed array, instead
of passing the class representation of the data type that the new
array is going to hold. This works around the Generics
limitations, because you don't ever pass raw data types directly
this way, they're always encapsulated in an array object.
I can't see any reason why you shouldn't be able to use this
version instead of yours. You're just going to have a couple more
brackets in your code, but that should be worth it... :-)
-Daniel
Am 13.12.2006 um 19:02 schrieb Aeon B. C. Lee:
I am writing some compression algorithms for huge data sets that
have to be as fast and compact as possible, and Java Generics is
simply too damn wasteful in memory usage.
Trust me, I have good reason to work around this silly problem.
So do you know any tool for editing Java class files?
Thanks, Aeon
On Dec 13, 2006, at 12:47 PM, DrAnonymous wrote:
I'm a tad confused. Why are you going through all the trouble
to make this work? The last post Aeon asked about hand hacking
the compiled class files. That sounds pretty desperate. Isn't
there some other way to code things to get at the functionality
you need?
Can anyone enlighten me?
Regards,
Aaron R>
On 12/13/06, Aeon B. C. Lee <email@hidden > wrote:
Yes, you have nailed it.
So if I remove the checkcast instructions, the code will be just
fine. Do you know any handy tool to edit the compiled class file?
Thanks, Aeon
On Dec 13, 2006, at 10:49 AM, Jerry wrote:
Hi,
Yes, I agree that it's a bug. I think the problem is that the
function definition and its call are both fine in isolation,
but not when put together (and I'm glad that I don't have to
try and write the code which would spot this at compile time).
The annoying thing is that if the compiler didn't issue the
checkcast instruction at the end of your function, I think the
code would work fine. The compiler is making the faulty
assumption that T[] is an Object[] when in your case it isn't.
class Array extends java.lang.Object{
Array();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
static java.lang.Object[] create(java.lang.Class, int);
Code:
0: getstatic #2; //Field java/lang/System.out:Ljava/
io/PrintStream;
3: aload_0
4: invokevirtual #3; //Method java/io/
PrintStream.println:(Ljava/lang/Object;)V
7: aload_0
8: iload_1
9: invokestatic #4; //Method java/lang/reflect/
Array.newInstance:(Ljava/lang/Class;I)Ljava/lang/Object;
12: checkcast #5; //class "[Ljava/lang/Object;"
15: checkcast #5; //class "[Ljava/lang/Object;"
18: areturn
}
Jerry
On 13 Dec 2006, at 15:20, Aeon B. C. Lee wrote:
Thanks. I know that Java Generics doesn't support primitives,
but that is a entirely different bug.
Please note that the following statement
byte[] b = (byte[])java.lang.reflect.Array.newInstance
(byte.class, 10);
is perfectly legal, because "The primitive Java types
(boolean, byte, char, short, int, long, float, and double),
and the keyword void are also represented as Class objects"
My code compiles without any problem, but gets a "
java.lang.ClassCastException: [B cannot be cast to
[Ljava.lang.Object" at runtime, which is just nonsense because
the cast is from array of byte to array of T (where T is byte).
Aeon
On Dec 13, 2006, at 9:10 AM, Jerry wrote:
On 13 Dec 2006, at 13:59, Aeon B. C. Lee wrote:
Can anyone tell me what's wrong with the last statement of
my code?
class Array
{
static <T> T[] create(Class<T> type, int length)
{
return (T[]) java.lang.reflect.Array.newInstance
(type, length);
}
}
public class NewMain
{
public static void main(String[] args)
{
byte[] b = (byte[])java.lang.reflect.Array.newInstance
(byte.class, 10); // This is OK
System.out.println(Array.create(Byte.class, 10)); //
So is this
System.out.println(Array.create (byte.class,
10)); // WTF is wrong with this?
}
}
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4487555
Jerry
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/java-dev/cybereer%
40gmail.com
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list ( email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/java-dev/antamiga%
40gmail.com
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/java-dev/cybereer%
40gmail.com
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/java-dev/email@hidden
This email sent to email@hidden
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/java-dev/email@hidden
This email sent to email@hidden