Java-Gaming.org    
Featured games (91)
games approved by the League of Dukes
Games in Showcase (580)
games submitted by our members
Games in WIP (500)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  I've always wondered why generics mess this up  (Read 2904 times)
0 Members and 1 Guest are viewing this topic.
Offline K.I.L.E.R

Senior Member




Java games rock!


« Posted 2005-04-08 11:59:22 »

I figured generics would create *less* work for me and more extensible architectures.

This is what it comes down to:
1  
2  
3  
4  
5  
6  
public Keys[] getKeys()
      {
            Keys[] keys = new Keys[this.keys.size()];
            System.arraycopy(this.keys.toArray(), 0, keys, 0, this.keys.size());
            return keys;
      }


Everytime I use "collection.toArray()" and cast it to "(Type[])collection.toArray()" I get a ClassCastException.
I managed to do some reading on it and found out that it was the fault of generics.

What I want to know is if are Sun going to fix this issue? I have found absolutely no indication that they are.

However if they are going to fix the issue, are they going to replace type erasure in generics or will they opt for a walkaround?

Vorax:
Is there a name for a "redneck" programmer?

Jeff:
Unemployed. Wink
Offline Markus_Persson

JGO Wizard


Medals: 12
Projects: 19


Mojang Specifications


« Reply #1 - Posted 2005-04-08 12:09:38 »

collection.toArray() returns an Object[].
You can't cast an Object[] into a Type[] unless it actually IS a Type[] (or subclass thereof). You never could.

You're probably looking for collection.toArray(new Type[0]), as that will create a new Type[] big enough to hold the collection, and return that (as an Object[]).


Note that if you want to save some copying and allocation, you can do collection.toArray(new Type[collection.size()]).

Play Minecraft!
Offline Orangy Tang

JGO Kernel


Medals: 51
Projects: 11


Monkey for a head


« Reply #2 - Posted 2005-04-08 12:17:33 »

Quote
new Type[0]

Holy crap! That's legal and works? Oddly enough I've never even thought of trying to declare a zero-length array. Shocked

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #3 - Posted 2005-04-08 12:51:51 »

Quote

Holy crap! That's legal and works? Oddly enough I've never even thought of trying to declare a zero-length array. Shocked


Yup, it's the bog-standard way of utilizing the toArray method (that I've been using since 1.1.x to workaround the design flaws in the whole array-casting-scenario outlined here).

It's not nice as something to have to do, but as soon as you discover that xxx[] cannot be cast to yyy[] and understand why, it's easy to remember Smiley.

malloc will be first against the wall when the revolution comes...
Offline K.I.L.E.R

Senior Member




Java games rock!


« Reply #4 - Posted 2005-04-08 13:02:53 »

Neat, thanks for that.
I really should stop reading Sun's forums. :/

Vorax:
Is there a name for a "redneck" programmer?

Jeff:
Unemployed. Wink
Offline K.I.L.E.R

Senior Member




Java games rock!


« Reply #5 - Posted 2005-04-08 16:07:14 »

Another issue with generics.

I have basically hacked together a generic array because generics doesn't allow me to do so.
Honestly, Sun really needs to scrap the current implementation.

NOTE: This class isn't complete, just an example.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
public class FastestCollection<E>
{
      private E[] items;
      private int idx;
     
     
      public void add(E s) {            
            this.items[idx++] = s;
      }
     
      public void resize(E[] e)
      {
            if(e.length > items.length)
            {
                  System.arraycopy(items, 0, e, 0, e.length);
                  this.items = e;
            }
      }
     
      public void remove(E s) {
            for (int i=0; i < items.length; i++)
            {
                  if(items[i] == s)
                        items[i] = null;
            }
      }
     
      public boolean contains(E s) {
            boolean itemFound = false;
           
            for (int i=0; i < items.length; i++)
            {
                  if(items[i] == s)
                  {
                        itemFound = true;
                        break;
                  }
            }
           
            return itemFound;
      }
     
     
      public FastestCollection(E[] v) {
            items = v;
      }

      /* (non-Javadoc)
       * @see java.util.ArrayList#size()
       */

      public int size()
      {
            return items.length;
      }

      /**
       * @param e An array of the type
       * @return
       */

      public E[] getStates(E[] e)
      {
            return this.items;
      }
}


It's sick. It's reall, really sick.
Maybe I should just stick to the collections framework and rework my own custom fast collection? Looks like I have no choice.

Vorax:
Is there a name for a "redneck" programmer?

Jeff:
Unemployed. Wink
Offline Orangy Tang

JGO Kernel


Medals: 51
Projects: 11


Monkey for a head


« Reply #6 - Posted 2005-04-08 16:17:15 »

I love it when people write things like FastestCollection, FastRand, etc. It implies that they wrote a corresponding SlowCollection, SlowRand as well just for the hell of it. Grin

[ TriangularPixels.com - Play Growth Spurt, Rescue Squad and Snowman Village ] [ Rebirth - game resource library ]
Offline K.I.L.E.R

Senior Member




Java games rock!


« Reply #7 - Posted 2005-04-08 16:47:12 »

Quote
I love it when people write things like FastestCollection, FastRand, etc. It implies that they wrote a corresponding SlowCollection, SlowRand as well just for the hell of it. Grin


I did.
Before my "SlowestCollection" class returns a result, it casts 10000 strings to objects and back to strings again.

Vorax:
Is there a name for a "redneck" programmer?

Jeff:
Unemployed. Wink
Offline swpalmer

JGO Coder




Where's the Kaboom?


« Reply #8 - Posted 2005-04-09 01:59:34 »

Quote


Yup, it's the bog-standard way of utilizing the toArray method


Actually you can be explicit and do:
1  
Type [] blah = (Type[])list.toArray(new Type[list.size()]);


Then toArray will use the actual array that you pass it and not have to allocate another one.

Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #9 - Posted 2005-04-09 12:38:59 »

Quote


Actually you can be explicit and do:
1  
Type [] blah = (Type[])list.toArray(new Type[list.size()]);


Then toArray will use the actual array that you pass it and not have to allocate another one.


/me stands corrected Smiley

I suppose "bog standard" doesn't necessarily mean "optimal" Wink

malloc will be first against the wall when the revolution comes...
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline K.I.L.E.R

Senior Member




Java games rock!


« Reply #10 - Posted 2005-04-10 08:36:16 »

Can someone explain why Eclipse doesn't like this?
ArrayList does this.

1  
Type[] arrayType = (Type[])new Object[5];



Vorax:
Is there a name for a "redneck" programmer?

Jeff:
Unemployed. Wink
Offline Markus_Persson

JGO Wizard


Medals: 12
Projects: 19


Mojang Specifications


« Reply #11 - Posted 2005-04-10 10:51:22 »

Quote


Actually you can be explicit and do:
1  
Type [] blah = (Type[])list.toArray(new Type[list.size()]);


Then toArray will use the actual array that you pass it and not have to allocate another one.


Quote
[...]
Note that if you want to save some copying and allocation, you can do collection.toArray(new Type[collection.size()]).


Ok, so I don't know what "copying" I speak about getting saved there. Wink But it made sense at the time.

Play Minecraft!
Offline tom
« Reply #12 - Posted 2005-04-10 12:15:24 »

Quote
Can someone explain why Eclipse doesn't like this?
ArrayList does this.

1  
Type[] arrayType = (Type[])new Object[5];



That is not whay ArrayList does. It uses reflection to create an array of the correct type.

Offline K.I.L.E.R

Senior Member




Java games rock!


« Reply #13 - Posted 2005-04-11 12:12:56 »

Quote

That is not whay ArrayList does. It uses reflection to create an array of the correct type.


No! It does that. I copied it straight from the Java ArrayList source code and changed it.

Vorax:
Is there a name for a "redneck" programmer?

Jeff:
Unemployed. Wink
Offline Markus_Persson

JGO Wizard


Medals: 12
Projects: 19


Mojang Specifications


« Reply #14 - Posted 2005-04-11 13:53:48 »

No, it doesn't. That cast is not legal java.


[edit:]
Just to prove you wrong, I checked the code for ArrayList:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
public Object[] toArray(Object a[]) {
  if (a.length < size)
    a = (Object[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);
  System.arraycopy(elementData, 0, a, 0, size);

  if (a.length > size)
    a[size] = null;

  return a;
}

Play Minecraft!
Offline Spasi
« Reply #15 - Posted 2005-04-11 14:41:56 »

Quote
No, it doesn't. That cast is not legal java.


Actually, it IS legal java, you only get a compiler warning. And ArrayList indeed uses such a statement, but only for its internal array. Reflection is only used for the type-safe toArray you mentioned (there's also the old toArray that returns a new Object[]).
Offline Markus_Persson

JGO Wizard


Medals: 12
Projects: 19


Mojang Specifications


« Reply #16 - Posted 2005-04-11 14:51:26 »

Holy moly, is it!

Thanks for correcting me. =)
It lead to some interesting reading about array type safety checks.


[edit:]
Premature correction. Check two posts down.

Play Minecraft!
Offline K.I.L.E.R

Senior Member




Java games rock!


« Reply #17 - Posted 2005-04-11 21:39:38 »

Care to fill me in?
BTW why is it a compiler warning?

Quote
Holy moly, is it!

Thanks for correcting me. =)
It lead to some interesting reading about array type safety checks.


Vorax:
Is there a name for a "redneck" programmer?

Jeff:
Unemployed. Wink
Offline Markus_Persson

JGO Wizard


Medals: 12
Projects: 19


Mojang Specifications


« Reply #18 - Posted 2005-04-12 07:40:15 »

Compare:

String string = (String)new Object();
String[] strings = (Strings[])new Object[10];

The first one obviously won't work.
The second one will break the following method, as you can pass an Integer[] that contains, say, a String:

1  
2  
3  
4  
5  
6  
7  
private static void printAll(Integer[] ints)
{
      for (int i = 0; i < ints.length; i++)
      {
            System.out.println(ints[i].intValue());
      }
}



However, I exerimented some, and it seems you really CAN'T do that cast after all:

1  
2  
3  
4  
5  
6  
7  
public class A
{
      public static void main(String[] args)
      {
            Integer[] test = (Integer[])new Object[0];
      }
}


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
C:\foo>javac A.java

C:\foo>java A
Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object;
        at A.main(A.java:5)

C:\foo>java -version
java version "1.5.0_02"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_02-b09)
Java HotSpot(TM) Client VM (build 1.5.0_02-b09, mixed mode)


So now I'm confused.

Play Minecraft!
Offline Spasi
« Reply #19 - Posted 2005-04-12 08:59:32 »

Quote
So now I'm confused.


It is valid java code, because you can have something like this:

1  
2  
Object[] unknown = new String[10];
String[] ok = (String[])unknown;

You need to able to perform such a cast, so it's not an error. It's a warning though, because the compiler cannot make sure that the cast will succeed; it's up to the programmer.
Offline Markus_Persson

JGO Wizard


Medals: 12
Projects: 19


Mojang Specifications


« Reply #20 - Posted 2005-04-12 10:02:27 »

The java code K.I.L.E.R posted, and the one you claimed was in ArrayList (can't find it personally) is not valid java code in the sense that it would always throw a runtime exception and fail.

"(String)new Object();" will compile, but it will always fail at runtime, just like "(String[])new Object[];" will.
And I don't think anyone would say that "(String)new Object();" is valid java code.

Play Minecraft!
Offline Spasi
« Reply #21 - Posted 2005-04-12 10:19:57 »

Quote
The java code K.I.L.E.R posted, and the one you claimed was in ArrayList (can't find it personally) is not valid java code in the sense that it would always throw a runtime exception and fail.


ArrayList is doing this in its ArrayList(int initialCapacity) constructor. But the cast there is for a generic type E (I'm assuming K.I.L.E.R was trying to do the same), which won't produce any exception (because no cast will be made).

Anyway, such a cast is valid java code in the sense that it will compile just fine. Agreed on it being stupid and dangerous though. Wink
Offline K.I.L.E.R

Senior Member




Java games rock!


« Reply #22 - Posted 2005-04-12 13:18:41 »

So why doesn't Sun just follow C# and implement a real version of generics?

Vorax:
Is there a name for a "redneck" programmer?

Jeff:
Unemployed. Wink
Offline Mark Thornton

Senior Member





« Reply #23 - Posted 2005-04-13 07:49:46 »

Quote
So why doesn't Sun just follow C# and implement a real version of generics?

Backward compatibility. You either have a completely new set of classes (such as Collections) for generic use, or insist that all existing code is at least recompiled.
Sun wanted existing byte code to keep working.
Offline K.I.L.E.R

Senior Member




Java games rock!


« Reply #24 - Posted 2005-04-13 10:50:53 »

Can't we have both?

Quote

Backward compatibility. You either have a completely new set of classes (such as Collections) for generic use, or insist that all existing code is at least recompiled.
Sun wanted existing byte code to keep working.


Vorax:
Is there a name for a "redneck" programmer?

Jeff:
Unemployed. Wink
Offline blahblahblahh

JGO Coder


Medals: 1


http://t-machine.org


« Reply #25 - Posted 2005-04-13 11:31:28 »

Quote
Can't we have both?



Of course. But we don't. And that is something that should put a certain amount of fear in each of use w.r.t. Sun's ongoing (in)ability not to screw-up java. But that's been discussed at length here already.

malloc will be first against the wall when the revolution comes...
Offline K.I.L.E.R

Senior Member




Java games rock!


« Reply #26 - Posted 2005-04-13 12:46:37 »

Unfortunately this leads to frustration.
How big of an impact will .NET 2.0 have on Sun?
Will Sun be pushed further to improve Java at a faster pace?


Quote


Of course. But we don't. And that is something that should put a certain amount of fear in each of use w.r.t. Sun's ongoing (in)ability not to screw-up java. But that's been discussed at length here already.


Vorax:
Is there a name for a "redneck" programmer?

Jeff:
Unemployed. Wink
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

xsi3rr4x (46 views)
2014-04-15 18:08:23

BurntPizza (42 views)
2014-04-15 03:46:01

UprightPath (58 views)
2014-04-14 17:39:50

UprightPath (40 views)
2014-04-14 17:35:47

Porlus (56 views)
2014-04-14 15:48:38

tom_mai78101 (79 views)
2014-04-10 04:04:31

BurntPizza (138 views)
2014-04-08 23:06:04

tom_mai78101 (238 views)
2014-04-05 13:34:39

trollwarrior1 (199 views)
2014-04-04 12:06:45

CJLetsGame (207 views)
2014-04-01 02:16:10
List of Learning Resources
by SHC
2014-04-18 03:17:39

List of Learning Resources
by Longarmx
2014-04-08 03:14:44

Good Examples
by matheus23
2014-04-05 13:51:37

Good Examples
by Grunnt
2014-04-03 15:48:46

Good Examples
by Grunnt
2014-04-03 15:48:37

Good Examples
by matheus23
2014-04-01 18:40:51

Good Examples
by matheus23
2014-04-01 18:40:34

Anonymous/Local/Inner class gotchas
by Roquen
2014-03-11 15:22:30
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!