That's cool. I agree with everything you have said. I guess that's why they didn't get me to write the generics spec. :)
I have a generics conundrum though and will post it on another thread. This one is getting long it in the tooth. On Jan 29, 10:52 am, Reinier Zwitserloot <[email protected]> wrote: > Christian: > > As James explained, that's the only way to do it. Unless you have a > better way. The one alternative strategy that is mainly used in C++ is > to create a whole new entire class file every time you need a new list > of X (which, by the way, quickly grows into the realm of crazy when > you apply this repeatedly for generics on generics, so when you start > having Map.Entry<Class<? extends Number>, Set<String>>, that is a > little nuts). > > Where-ever you read that T[] is always an Object[], was wrong, though > I suspect the text was mostly right if somewhat oversimplified, and > you misunderstood. You seem to be talking specifically about new T[], > which isn't even legal right now, but would be post-reification (and > do what you expect - if T was a string, that would create an array of > Strings). > > Again, your point of view is that 'this somehow needs to be better... > somehow'. People have had a deep long think on the topic and came up > with: There is no better way. If you do know of a better way, please, > enlighten us all. > > On Jan 29, 12:16 am, Christian Catchpole <[email protected]> > wrote: > > > Its not the actual cast that's annoying. Its the fact that.. > > > T getValue() > > > Where T = String > > > Reflection says that the method signature is still.. > > > Object getValue() > > > and the byte code looks like.. > > > (String)getValue() > > > My understanding as I mentioned earlier is that a generic class uses > > Object as it's type throughout - it's the caller the does type > > checking on the types. > > > But that would make sense that I can cast a HashMap<String,String> to > > HashMap and access it using Objects. Also why the cast needs to exist > > in case I then try to get one of those objects and it wasn't a String. > > > If that's the way it has to be then I guess thats all OK. It's just > > not how I expected generics to work. > > > As for the Object[] issue. What else would it use? It would use > > String[] rather than Object[] if T is String. But you seem to be > > saying that it's not the fault of generics, it's the fault of arrays > > themselves. I read somewhere that a T[] is always an Object[], but as > > you explain, it's not clear cut. > > > On Jan 29, 7:21 am, Reinier Zwitserloot <[email protected]> wrote: > > > > Of course ArrayList has to use an internal Object[]. What else would > > > it use? That's like whining about parts of java being written in C. > > > The core of the language isn't built the way you ought to be build > > > your own apps, because it has to work without the batteries (they ARE > > > the batteries). The point is, ArrayList already exists, so there's no > > > need for you to do what it does to make it work. > > > > So, if I understand you right, Christian, you're annoyed that the > > > class file bytecode generated when you use generics still contains > > > casts? Why? > > > > The JIT compiler will, by the way, indeed eliminate casts when > > > compiling a fragment to native code. There's one general rule I adhere > > > to when looking at generated bytecode: Unless I know exactly what the > > > JIT compiler does with it, there is absolutely _no point whatsoever_ > > > in trying to assess if this is 'nice' or 'efficient'. I suggest you do > > > the same - that JIT compiler gets some seriously complex stuff just > > > right, but at the same time, some fairly simple stuff is beyond its > > > ability to smartly reduce. There's just no way a mere mortal is going > > > to discern post-JIT efficiency of anything by just looking at the > > > bytecode. > > > > checked exceptions are a 'caller side typecheck facade'. So are import > > > statements. So are break and continue. Do all of those get the same > > > disdainful treatment that you give generics? > > > > Your understanding is also wrong. You say: > > > > > An ArrayList<String> is just an ArrayList with type checks on input and > > > > output. > > > > This is _WRONG_. An ArrayList<String> is just an ArrayList with > > > absolutely no type checks anywhere. The compiler (at compile time, > > > obviously) susses out that there is no possible way that, at runtime, > > > things can go wrong, and therefore inserts the one cast you'd need > > > (when reading) for you. If it is certain things are going to go wrong, > > > it will error. If it doesn't know because you're using legacy code or > > > you're trying to do things that the generics system doesn't support, > > > it will warn. > > > > So, to be exact, in the following code, the ONLY difference when > > > adding <String> to the list types is that the (String) in the snippet > > > below goes from 'must be there' to 'if you don't put it there, the > > > compiler will silently insert it for you'. That's the only thing: > > > > List list = new ArrayList(); > > > list.add("foobar"); > > > String x = (String) list.get(0); > > > > As I mentioned before, the relationship between 'bytecode generated' > > > and 'magic tricks done by the JIT compiler' is so loose, that this > > > cannot be taken to mean that at JIT time, there's the penalty of doing > > > a typecheck. In most tight loop situations, the JIT compiler, > > > completely independent from javac, ascertains the safety of the > > > involved operation, and eliminates the typecheck entirely. > > > > As far as T.class goes: That is actually legal java code, though as > > > per the JLS, it won't actually work. The failure occurs not at the > > > parsing level, and not even at the semantics level, but at the 'make > > > the bytecode for this AST node' level. It is therefore semantically > > > correct that IntelliJ offers the auto-complete. It is not practically > > > correct, though, obviously. Someone at IntelliJ needs to add a rule to > > > not do that. (auto-completing something that doesn't work is teh dumb > > > - let's go IntelliJ apologists!) > > > > On Jan 28, 4:34 am, Christian Catchpole <[email protected]> > > > wrote: > > > > > I'm trying to find the links but I'm sure I was reading about how > > > > ArrayList internally uses an Object[]. Because it needs to construct > > > > the array and it's not passed in. > > > > >http://www.docjar.com/html/api/java/util/ArrayList.java.html > > > > > When generics first came along I thought 'great, no more casting'. So > > > > I disassembled some source, only to find that casts still do exist > > > > after the caller calls a generified method. This is because generics > > > > can still be subverted with casts. > > > > > (Now I would hope that the JIT could detect cases where subversion > > > > can't occur and remove the cast, but that's another story). > > > > > My assumption was that generics is a 'caller side typecheck facade'. > > > > An ArrayList<String> is just an ArrayList with type checks on input > > > > and output. Hence my definition of 'bollocks'. > > > > > But I have been known to be wrong about some things on rare occasion. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "The Java Posse" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/javaposse?hl=en -~----------~----~----~----~------~----~------~--~---
