TheServerSide recently interviewed Joshua Bloch, author of the Collections framework, java.math, the book Effective Java, etc. Joshua discusses new Java language features scheduled for the Java 1.5 'Tiger' release including Typesafe Enums, autoboxing, static imports, and generics. He also talks about the various people, groups and institutions that are driving the Java language forward.
Watch Joshua Bloch's Interview.
-
Tech Talk with Joshua Bloch on New Java Language Constructs (124 messages)
- Posted by: Nitin Bharti
- Posted on: April 09 2003 20:27 EDT
Threaded Messages (124)
- Tech Talk with Joshua Bloch on What's New in Java 1.5 by Maris Orbidans on April 10 2003 08:06 EDT
- Tech Talk with Joshua Bloch on What's New in Java 1.5 by Maris Orbidans on April 10 2003 08:11 EDT
-
static import of methods? by Martin Devlin on April 10 2003 01:33 EDT
- static import of methods? by Vlad Ender on April 10 2003 05:11 EDT
-
Tech Talk with Joshua Bloch on What's New in Java 1.5 by aaron evans on April 10 2003 09:59 EDT
- Tech Talk with Joshua Bloch on What's New in Java 1.5 by surajeet dev on April 11 2003 01:10 EDT
- What's the point for static import? by Frankie Lam on May 28 2003 02:16 EDT
-
static import of methods? by Martin Devlin on April 10 2003 01:33 EDT
- Tech Talk with Joshua Bloch on What's New in Java 1.5 by Maris Orbidans on April 10 2003 08:11 EDT
- Tech Talk with Joshua Bloch on New Java Language Constructs by Herve Tchepannou on April 10 2003 10:49 EDT
- waht about gilad? by Paulo Silveira on April 10 2003 12:22 EDT
- Mea Culpa by Joshua Bloch on April 10 2003 13:38 EDT
-
Restraint appreciated. by Robert Devi on April 10 2003 04:50 EDT
- Resource management yuck (was: Restraint appreciated). by Valentin Sliouniaev on April 10 2003 08:23 EDT
-
Well I hope I'm not the only one who thinks these are BAD ideas by Shai Almog on April 11 2003 02:58 EDT
- RE: these are BAD ideas by Ara Abrahamian on April 11 2003 03:56 EDT
-
Well I hope I'm not the only one who thinks these are BAD ideas by Mileta Cekovic on April 11 2003 04:57 EDT
-
Well I hope I'm not the only one who thinks these are BAD ideas by Shai Almog on April 13 2003 08:55 EDT
-
Well I hope I'm not the only one who thinks these are BAD ideas by Valentin Sliouniaev on April 13 2003 09:39 EDT
- Well I hope I'm not the only one who thinks these are BAD ideas by Shai Almog on April 13 2003 02:08 EDT
-
Well I hope I'm not the only one who thinks these are BAD ideas by Valentin Sliouniaev on April 13 2003 09:39 EDT
-
Well I hope I'm not the only one who thinks these are BAD ideas by Shai Almog on April 13 2003 08:55 EDT
- Voting against RFE's by Luc Peerdeman on April 11 2003 05:21 EDT
-
Re: BAD ideas by David Hamilton on April 11 2003 05:35 EDT
-
Re: BAD ideas by Shai Almog on April 13 2003 09:17 EDT
- Re: BAD ideas by David Hamilton on April 14 2003 08:30 EDT
-
Generics by Brian Sayatovic on April 15 2003 09:21 EDT
- Generics by Shai Almog on April 15 2003 10:10 EDT
- Autoboxing by Brian Sayatovic on April 15 2003 09:22 EDT
-
Re: BAD ideas by Shai Almog on April 13 2003 09:17 EDT
-
ClassCastExceptions on Generics by David Hamilton on April 11 2003 06:23 EDT
- JDK1.5 Features by Dean Sheppard on April 11 2003 08:26 EDT
-
Why add static imports ? by Maris Orbidans on April 11 2003 08:27 EDT
- Handle it the same way by Brian Sayatovic on April 15 2003 09:26 EDT
-
ClassCastExceptions on Generics by Shai Almog on April 13 2003 09:24 EDT
-
ClassCastExceptions on Generics by David Hamilton on April 14 2003 11:29 EDT
-
ClassCastExceptions on Generics by Shai Almog on April 15 2003 01:33 EDT
-
ClassCastExceptions on Generics by David Hamilton on April 15 2003 06:40 EDT
-
ClassCastExceptions on Generics by Shai Almog on April 15 2003 10:38 EDT
-
ClassCastExceptions on Generics by David Hamilton on April 15 2003 11:19 EDT
-
ClassCastExceptions on Generics by Shai Almog on April 15 2003 01:04 EDT
-
ClassCastExceptions on Generics by Robert Devi on April 15 2003 02:38 EDT
- ClassCastExceptions on Generics by Shai Almog on April 16 2003 01:17 EDT
-
ClassCastExceptions on Generics by David Hamilton on April 16 2003 04:22 EDT
- ClassCastExceptions on Generics by Shai Almog on April 16 2003 06:15 EDT
-
ClassCastExceptions on Generics by Robert Devi on April 15 2003 02:38 EDT
-
ClassCastExceptions on Generics by Shai Almog on April 15 2003 01:04 EDT
-
ClassCastExceptions on Generics by David Hamilton on April 15 2003 11:19 EDT
-
ClassCastExceptions on Generics by Shai Almog on April 15 2003 10:38 EDT
-
ClassCastExceptions on Generics by David Hamilton on April 15 2003 06:40 EDT
-
ClassCastExceptions on Generics by Shai Almog on April 15 2003 01:33 EDT
-
ClassCastExceptions on Generics by David Hamilton on April 14 2003 11:29 EDT
- Well I hope I'm not the only one who thinks these are BAD ideas by Joshua Y on April 11 2003 11:18 EDT
-
Well I hope I'm not the only one who thinks these are BAD ideas by Tero Vaananen on April 11 2003 11:43 EDT
-
Well I hope I'm not the only one who thinks these are BAD ideas by Joshua Y on April 11 2003 01:44 EDT
-
Well I hope I'm not the only one who thinks these are BAD ideas by Robert Devi on April 11 2003 03:21 EDT
- "JVM Code" by Toby Reyelts on April 11 2003 04:38 EDT
- Grey areas by Valentin Sliouniaev on April 11 2003 04:46 EDT
- Well I hope I'm not the only one who thinks these are BAD ideas by Shai Almog on April 11 2003 05:36 EDT
- Well I hope I'm not the only one who thinks these are BAD ideas by Shai Almog on April 13 2003 08:12 EDT
-
Well I hope I'm not the only one who thinks these are BAD ideas by Robert Devi on April 11 2003 03:21 EDT
- enums are the worst by aaron evans on April 15 2003 01:26 EDT
-
Well I hope I'm not the only one who thinks these are BAD ideas by Joshua Y on April 11 2003 01:44 EDT
- Well I hope I'm not the only one who thinks these are BAD ideas by Rashid Jilani on April 11 2003 02:18 EDT
-
Typesafe Enums and Generics are very much worth their while by Henrik Klagges on April 11 2003 03:14 EDT
-
Typesafe Enums and Generics are very much worth their while by Shai Almog on April 11 2003 04:36 EDT
-
Typesafe Enums and Generics are very much worth their while by David Hamilton on April 14 2003 07:57 EDT
-
Typesafe Enums and Generics are very much worth their while by Shai Almog on April 14 2003 11:49 EDT
-
Typesafe Enums and Generics are very much worth their while by David Hamilton on April 14 2003 12:33 EDT
-
Typesafe Enums and Generics are very much worth their while by Shai Almog on April 15 2003 03:29 EDT
-
Typesafe Enums and Generics are very much worth their while by David Hamilton on April 15 2003 05:38 EDT
-
Typesafe Enums and Generics are very much worth their while by Shai Almog on April 15 2003 11:14 EDT
-
Typesafe Enums and Generics are very much worth their while by David Hamilton on April 16 2003 04:42 EDT
- Typesafe Enums and Generics are very much worth their while by Shai Almog on April 16 2003 06:24 EDT
-
Typesafe Enums and Generics are very much worth their while by David Hamilton on April 16 2003 04:42 EDT
-
Typesafe Enums and Generics are very much worth their while by Shai Almog on April 15 2003 11:14 EDT
-
Typesafe Enums and Generics are very much worth their while by David Hamilton on April 15 2003 05:38 EDT
-
Typesafe Enums and Generics are very much worth their while by Shai Almog on April 15 2003 03:29 EDT
-
Typesafe Enums and Generics are very much worth their while by David Hamilton on April 14 2003 12:33 EDT
-
Typesafe Enums and Generics are very much worth their while by Shai Almog on April 14 2003 11:49 EDT
-
Prefer not to work for Shai by Robert White on April 16 2003 06:55 EDT
-
Prefer not to work for Shai (not much of a chance) by Shai Almog on April 17 2003 04:51 EDT
-
I remain unconvinced of the danger of Enumerated types by Robert White on April 18 2003 12:42 EDT
- I remain unconvinced of the danger of Enumerated types (part 1) by Shai Almog on April 18 2003 10:00 EDT
-
I remain unconvinced of the danger of Enumerated types (part 2) by Shai Almog on April 18 2003 10:01 EDT
- RE: I remain unconvinced of the danger of Enumerated types by Cameron Zemek on July 13 2003 11:19 EDT
-
I remain unconvinced of the danger of Enumerated types by Robert White on April 18 2003 12:42 EDT
- Prefer not to work by Valentin Sliouniaev on April 17 2003 05:21 EDT
-
Prefer not to work for Shai (not much of a chance) by Shai Almog on April 17 2003 04:51 EDT
-
Typesafe Enums and Generics are very much worth their while by David Hamilton on April 14 2003 07:57 EDT
-
Typesafe Enums and Generics are very much worth their while by Shai Almog on April 11 2003 04:36 EDT
-
Is it bad to have good ideas? by Valentin Sliouniaev on April 11 2003 03:21 EDT
-
Is it bad to have good ideas? by Shai Almog on April 11 2003 04:53 EDT
-
Is it bad to have good ideas? by Valentin Sliouniaev on April 11 2003 06:05 EDT
-
Is it bad to have good ideas? by Shai Almog on April 11 2003 06:38 EDT
-
Is it bad to have good ideas? by David McCoy on April 11 2003 07:43 EDT
- Is it bad to have good ideas? by Shai Almog on April 12 2003 02:56 EDT
-
Is it bad to have good ideas? by Valentin Sliouniaev on April 11 2003 08:05 EDT
-
Is it bad to have good ideas? by Mike Spille on April 11 2003 08:19 EDT
-
Is it bad to have good ideas? by Valentin Sliouniaev on April 12 2003 08:01 EDT
-
Is it bad to have good ideas? by Mike Spille on April 12 2003 11:14 EDT
-
Bit fields are not enums by Valentin Sliouniaev on April 13 2003 08:51 EDT
-
Bit fields are not enums by Mike Spille on April 13 2003 02:44 EDT
-
Bit fields are not enums by Valentin Sliouniaev on April 13 2003 04:51 EDT
-
Bit fields are not enums by Mike Spille on April 13 2003 07:57 EDT
- Bit fields are not enums by Valentin Sliouniaev on April 13 2003 09:25 EDT
- Value objects by Valentin Sliouniaev on April 13 2003 09:52 EDT
-
Bit fields are not enums by Mike Spille on April 13 2003 07:57 EDT
-
Bit fields are not enums by Valentin Sliouniaev on April 13 2003 04:51 EDT
-
Bit fields are not enums by Mike Spille on April 13 2003 02:44 EDT
-
Is it bad to have good ideas? by Valentin Sliouniaev on April 13 2003 09:21 EDT
- Is it bad to have good ideas? by Mike Spille on April 13 2003 03:06 EDT
-
Bit fields are not enums by Valentin Sliouniaev on April 13 2003 08:51 EDT
-
Is it bad to have good ideas? by Mike Spille on April 12 2003 11:14 EDT
-
Is it bad to have good ideas? by Valentin Sliouniaev on April 12 2003 08:01 EDT
-
Is it bad to have good ideas? by Shai Almog on April 12 2003 03:14 EDT
- Is it bad to have good ideas? by Robert Devi on April 12 2003 11:14 EDT
-
Is it bad to have good ideas? by Valentin Sliouniaev on April 12 2003 07:41 EDT
-
Is it bad to have good ideas? by Shai Almog on April 13 2003 03:07 EDT
-
Is it bad to have good ideas? by Valentin Sliouniaev on April 13 2003 08:32 EDT
-
Is it bad to have good ideas? by Shai Almog on April 13 2003 03:01 EDT
-
Is it bad to have good ideas? by Mike Spille on April 13 2003 04:02 EDT
- Is it bad to have good ideas? by Shai Almog on April 14 2003 02:34 EDT
-
Is it bad to have good ideas? by Mike Spille on April 13 2003 04:02 EDT
-
Is it bad to have good ideas? by Shai Almog on April 13 2003 03:01 EDT
-
Is it bad to have good ideas? by Valentin Sliouniaev on April 13 2003 08:32 EDT
-
Is it bad to have good ideas? by Shai Almog on April 13 2003 03:07 EDT
-
Is it bad to have good ideas? by Mike Spille on April 11 2003 08:19 EDT
-
Is it bad to have good ideas? by David McCoy on April 11 2003 07:43 EDT
-
Is it bad to have good ideas? by Shai Almog on April 11 2003 06:38 EDT
-
hardcoded still by thoff thoff on April 14 2003 09:50 EDT
-
hardcoded still by Shai Almog on April 14 2003 11:09 EDT
-
hardcoded still by thoff thoff on April 14 2003 12:33 EDT
-
hardcoded still by Shai Almog on April 15 2003 01:57 EDT
- hardcoded still by Shai Almog on April 15 2003 03:35 EDT
-
hardcoded still by Shai Almog on April 15 2003 01:57 EDT
-
hardcoded still by thoff thoff on April 14 2003 12:33 EDT
-
hardcoded still by Shai Almog on April 14 2003 11:09 EDT
-
Is it bad to have good ideas? by Valentin Sliouniaev on April 11 2003 06:05 EDT
-
Is it bad to have good ideas? by Shai Almog on April 11 2003 04:53 EDT
- Are enums limited? by Piotr Zakrzewski on April 14 2003 06:47 EDT
-
Restraint appreciated. by Robert Devi on April 10 2003 04:50 EDT
- Mea Culpa by Joshua Bloch on April 10 2003 13:38 EDT
- Text of the Tech Talk ? by Hemant Gohil on April 10 2003 12:48 EDT
- Thumbs Up by Dmitriy Setrakyan on April 10 2003 13:43 EDT
- Tech Talk with Joshua Bloch on New Java Language Constructs by Francis Amanfo on April 10 2003 14:06 EDT
- Java version numbers... by null on April 10 2003 14:56 EDT
- Java version naming by Scott Hodson on April 10 2003 05:20 EDT
- Java version numbers... by null on April 10 2003 14:56 EDT
- Removal of deprecated members? by Brett Hovenkotter on April 10 2003 15:47 EDT
- Battle test Java (with C# :-) by Valentin Sliouniaev on April 10 2003 20:35 EDT
- battle testing by jon harper on April 11 2003 01:54 EDT
- battle testing by Mileta Cekovic on April 11 2003 05:03 EDT
- battle testing by jon harper on April 11 2003 01:54 EDT
- Removing features by Brian Matzon on April 11 2003 02:59 EDT
- Removing features by Mileta Cekovic on April 11 2003 04:43 EDT
-
Removing features by Valentin Sliouniaev on April 11 2003 09:01 EDT
- Removing features by David Hamilton on April 11 2003 10:05 EDT
-
Removing features by Maris Orbidans on April 11 2003 01:25 EDT
-
Removing features by bob farmer on April 11 2003 02:32 EDT
- Removing features by Valentin Sliouniaev on April 12 2003 08:17 EDT
- Foo by Darius Cooper on July 25 2003 10:43 EDT
-
foo by thoff thoff on April 14 2003 09:50 EDT
- foo by James Hollow on May 12 2003 11:49 EDT
- What 'foo' is.... by James Shipley on May 07 2004 11:33 EDT
-
Removing features by bob farmer on April 11 2003 02:32 EDT
-
Removing features by Valentin Sliouniaev on April 11 2003 09:01 EDT
- Removing features by Mileta Cekovic on April 11 2003 04:43 EDT
- Concurrency Libraries by David Hamilton on April 11 2003 10:52 EDT
- Concurrency Libraries by Massimo Luise on April 14 2003 03:35 EDT
- How about supporting Hot Deployment of classes by sean decor on April 11 2003 13:29 EDT
- New features influence changes in APIs by Nebojsa Vasiljevic on April 13 2003 07:03 EDT
- Enums will help debugging by Vilya Harvey on April 13 2003 18:42 EDT
-
Tech Talk with Joshua Bloch on What's New in Java 1.5[ Go to top ]
- Posted by: Maris Orbidans
- Posted on: April 10 2003 08:06 EDT
- in response to Nitin Bharti
so many cool new things... :-)
When the Tiger is scheduled to hit the streets ?
he said all things but this one. -
Tech Talk with Joshua Bloch on What's New in Java 1.5[ Go to top ]
- Posted by: Maris Orbidans
- Posted on: April 10 2003 08:11 EDT
- in response to Maris Orbidans
I am not sure whether the "static import" is very good.
I hope it will not turn Java programms into something like C++ with "global functions" without classes. I am sick of those every time I see C++. -
static import of methods?[ Go to top ]
- Posted by: Martin Devlin
- Posted on: April 10 2003 13:33 EDT
- in response to Maris Orbidans
A static import of constants I suppose might not be a bad thing though if it was my choice I would do without it.
Static import of methods - VERY BAD IDEA. So would it not be the case that calls to these methods will look like a call to the local class when in fact they are a call to some distant class? Thats like a global function.
Currently, a call to a static method reads well becuase we know which class it belongs to. This helps the readability of the code. I don't know why they want to diminish the readability of the code by changing it. The classname prefix may be cumbersome but at the end of the day it is for the greater good. -
static import of methods?[ Go to top ]
- Posted by: Vlad Ender
- Posted on: April 10 2003 17:11 EDT
- in response to Martin Devlin
Agreed. I don't like even the constants import - if you want a local access to them, use an interface to declare them and implement it. I think it's cleaner to do it that way as it makes it more explicit and is no harder (in terms of how much effort is required from a developer). And it doesn't introduce new things into language.
For similar reason, I would prefer a different implementation of the foreach. I would prefer to extend the Collection interface (or introduce a new one, which both Array and Collection would implement - which 1.5 does anyway, but it's just a tag) so that it would take a functor object which could execute something on every item in the collection. In previous versions, this wouldn't work with arrays, but with autoboxing it would be easy. The argument against this could be that it's slightly more work than foreach, but I would argue that it might actually be a good thing as it would force people to think more about what they do in their loops (and separate it cleanly out). I've seen too many for loops nested 3+ leves with various breaks and continues inside, and I suspect that making iteration easier will mean I will see even more of them.
Still, at least all the boilerplate in good code can disappear now :).
Not to mention I'm slightly split on 1.5 also because it will mean I will have to change a lot my code inspector :).
Regards,
Vlad -
Tech Talk with Joshua Bloch on What's New in Java 1.5[ Go to top ]
- Posted by: aaron evans
- Posted on: April 10 2003 21:59 EDT
- in response to Maris Orbidans
If you have ever created a Java class with a main function, you have used this. The ignorance of some Java developers still surprises me. -
Tech Talk with Joshua Bloch on What's New in Java 1.5[ Go to top ]
- Posted by: surajeet dev
- Posted on: April 11 2003 01:10 EDT
- in response to aaron evans
Dear Evans,
Please quote the original message.
R u ignorant abt what u r trying to say?
Not being able to say anything important on some topic doesnt mean that blabbering would be noticed too. -
What's the point for static import?[ Go to top ]
- Posted by: Frankie Lam
- Posted on: May 28 2003 14:16 EDT
- in response to Maris Orbidans
Current mechanism for using constants in source code requires a little more keystrokes, but certainly it is a clearer and better way to using them. I don't want to use something like "Object Browser" in VB for me to locate just a single Constant.
Another side effect is that creating a constant automatically by Eclipse when the symbol cannot be resolved cannot work anymore :-) -
Tech Talk with Joshua Bloch on New Java Language Constructs[ Go to top ]
- Posted by: Herve Tchepannou
- Posted on: April 10 2003 10:49 EDT
- in response to Nitin Bharti
Waon.. I can't wait to play with Tiger!
This will be a major improvement for the language, which hasn't really improved since the 1st release.
Too bad Josuah didn't talk about Metadata feature, which is to my point of view the most exciting feature!
Kudos for Sun! -
waht about gilad?[ Go to top ]
- Posted by: Paulo Silveira
- Posted on: April 10 2003 12:22 EDT
- in response to Nitin Bharti
Not saying ANYTHING about Gilad Bracha was really a shame -
Mea Culpa[ Go to top ]
- Posted by: Joshua Bloch
- Posted on: April 10 2003 13:38 EDT
- in response to Paulo Silveira
Yep, you're right. I'm sorry. Gilad Is co-leading JSR-201 (enums, foreach, autoboxing, static import) and leading JSR-14 (generics). He also maintains the Java Language Specification. He is enormously influential in ensuring the quality and integerity of all the language changes.
Several others at Sun also deserve mention (in addition to Neal Gafter and James Gosling, whom I did mention in the interview): Graham Hamilton, Tim Lindholm, Guy Steele, and Jim Waldo all played a big part in the early work surrounding the language JSRs.
Regards,
Josh -
Restraint appreciated.[ Go to top ]
- Posted by: Robert Devi
- Posted on: April 10 2003 16:50 EDT
- in response to Joshua Bloch
When I first came across C++, it was a really small but useful extension to C. Sure it didn't have many features, but it simple, easy to understand, and a vast improvement over regular C. Then it very legitimately added multiple inheritance (although it went overboard by adding multiple implementation inheritance), and it legitimately added exceptions, and it legitimately replaced the I/O library, and added templates, run-time type identification, and the STL. Even though each individual change was important and legitimate, the sum total of those changes turned C++ into the PL/1-like monster that it is now.
I'm glad that Java has a lot more restraint in adding language extensions. Java learned early the thing C programmers known for years: a limitted language with a great library is much better than a power language with a small library.
A great number of language extensions can be implemented through standard libraries. For example, come people have been asking for the C# using() statement to be added:
using (Resource valueableResource1 = GDIObjectThatMustBeReleasedAsSoonAsPossible()) {
// use resource valueableResource1
using (Resource valueableResource2 = GDIObjectThatMustBeReleasedAsSoonAsPossible()) {
// use resource valueableResource2 and valueableResource1
}
// use resource valueableResource1
}
// the "Destroy()" method is called on valueableResource1 to ensure it's freed.
// the "Destroy()" method is called on valueableResource2 to ensure it's freed.
It's possible to make a convincing case that sometimes you need to manage resources that tightly in many systems, this sort of resource scarcity and that the Java alternative is very messy (you need two nested try/finally blocks) so it's more error-prone.
Fortunately, there's a clean alternative: resource pools. The above code could be rewritten in Java as:
try {
Collection resourcePool = new List();
// use resource valueableResource1
ValuableResource valuableResource1, valuableResource2;
resourcePool.add(valuableResource1=new ValuableResource());
resourcePool.add(valuableResource2=new GDIObjectThatMustBeReleasedAsSoonAsPossible());
// use resource valueableResource2 and valueableResource1
}
finally {
// ensure that Destroy() method is called on each resource
ResourceManager.releaseResources(resourcePool);
}
Yes, it's a bit less eager to reclaim resources, and it's a bit longer, but it's more flexible. For instance, it can manage an array of resources while the using() clause can't. Adding the using() clause would only add complexity to the language.
A case can be made, however, that
* since different resources use different names of their "Destroy()" method (some use "close()", some use "free()", some use "destroy()", "deallocate()", and some use "cleanup())
* and each resource manager can only handle one type of resource
that it would benefit Java if the "Destroy()" and "resourceManager" classes were put in the standard library. Much the same reason was used when bool/true/false were added to C++ (i.e. to avoid having BOOLEAN/TRUE/FALSE mixed with boolean/true/false with int/0/1, etc in the same program).
This addition would make resource managers less error prone (since you have to worry about matching the resource type with the resource manager) and you could make standard types like files and socket (if done correctly). It would also allow the compiler to check to ensure that you're not using the resource after it's freed (in much the same way that some compilers warn if there are statements after an "java.lang.System.exit()" call). Essentially, all that would be required is that java.lang.Runtime.callFinalize(Collection resourcePool) be added to the library. When called, it would call the finalize() method of all objects in the collection. -
Resource management yuck (was: Restraint appreciated).[ Go to top ]
- Posted by: Valentin Sliouniaev
- Posted on: April 10 2003 20:23 EDT
- in response to Robert Devi
Shouldn't resourcePool be outside the try..finally?
ResourcePool resources = new ResourcePool();
try {
InputStream stream = ...
resources.add(stream);
File file = ...
resources.add(file);
} finally {
resources.release();
}
See also: http://www.research.att.com/~bs/bs_faq2.html#finally. -
Well I hope I'm not the only one who thinks these are BAD ideas[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 11 2003 02:58 EDT
- in response to Robert Devi
Java is going down the C# path... Up until now Java had simplicity going
for it, this will be lost with tiger and I will probably be forced to
upgrade to a language I don't even like anymore. While some of you may
say that I don't have to use these features, the libraries and API's
will start using them and thus force me to use them as well:
1. ENUM's are the absolute worst. They make my blood boil and every
programmer I see using them (in C++ as well) is fired on the spot.
Programmers who try to use ENUM "alternatives" such as small classes
or interger constants will never get promoted and need serious help
in understanding object oriented design. No OO language needs ENUM's.
2. Generics are just plain wrong, and even worse in the way they
are implemented. Did you know that it is still possible to get a
ClassCastException (or equivalent) when using generics in Java?
Generics is simply a different syntax for writing a cast, I think
programmers should be aware of what the language/VM is doing.
3. Autoboxing again is here to cut down on typing... As if typing
is a complicated part of the programming process. Its not as if
the VM is "really" changed, you end up writing one thing (adding
an int to a collection) which comes out as another thing alltogether.
This is one of the main problems and debugging pitfalls in C++
(anyone who ran a large enough real world C++ project knows this),
C++ "thinks" it knows what you want. This allows you to repeatedly
shoot yourself in the foot, due to a mistake made by a novice who
didn't understand the complexities of the language. No amount
of coding conventions or filtering of programmers can protect you
within a large team from the complications of the language.
4. Why add static imports is beyond me. It seems as if someone
in this horrible JSR team is using a really bad text editor and
wants to save a few keystrokes. Why not turn Java into a functional
language and get it over with.
Every SINGLE one of these features offers NO benefit whatsoever
to the language neither in performance nor in readability or
maintainance (every benefit gained in readability is offset
by the fact that your reading something that isn't realated
to whats really happening).
Languages should be complex in the API level and not in the
lanugage level. The API doesn't have wide sweeping effects on
the quality of the whole project.
I only wish that there was a way to vote against RFE's in the
sun bug parade. -
RE: these are BAD ideas[ Go to top ]
- Posted by: Ara Abrahamian
- Posted on: April 11 2003 03:56 EDT
- in response to Shai Almog
Yeah I don't find these enum/staticimport/etc stuff intersting at all. They are not much important at all imho. I just want two things in JDK 1.5:
- blocks, like Ruby
- runtime attributes, like C#
JSR 175 adds runtime attributes, but I don't know if blocks are in the agenda at all. Maybe part of the other jsr for adding foreach/etc? I hope foreach is implemented as a block. A richer runtime api would also be great ("give me all classes that implement Persistable and have @hibernate attribute").
Sun seems so conservative to add a interception mechanism to the language. CGLIB, aspectworks, nanning, blabla. We need a clean and standard way of doing it. We need a clean mechanism for adding/removing interceptors to classes when they are new-ed.
Ara. -
Well I hope I'm not the only one who thinks these are BAD ideas[ Go to top ]
- Posted by: Mileta Cekovic
- Posted on: April 11 2003 04:57 EDT
- in response to Shai Almog
Java is going down the C# path...
What is wrong with borrowing good things from C# ? At the end, C# borrowed much more from Java.
> 1. ENUM's are the absolute worst. They make my blood boil and every
> programmer I see using them (in C++ as well) is fired on the spot.
> Programmers who try to use ENUM "alternatives" such as small classes
> or interger constants will never get promoted and need serious help
> in understanding object oriented design. No OO language needs ENUM's.
And what about thousands of enum-like integer constants in Java libraries ? How would you replace them or how would you redesing public interfaces of these Java libraries to avoid them ?
> 2. Generics are just plain wrong, and even worse in the way they
> are implemented. Did you know that it is still possible to get a
> ClassCastException (or equivalent) when using generics in Java?
>Generics is simply a different syntax for writing a cast, I think
> programmers should be aware of what the language/VM is doing.
And how would you implement generics (the so wanted feature by many, many Java programmers) into Java language by not breaking byte code compatibility with older VMs ? Do you have better idea ?
> 3. Autoboxing again is here to cut down on typing...
> 4. Why add static imports is beyond me.
> Every SINGLE one of these features offers NO benefit whatsoever
> to the language neither in performance nor in readability or
> maintainance (every benefit gained in readability is offset
> by the fact that your reading something that isn't realated
> to whats really happening).
Saying that this changes do not improve readibility of Java language is at least not objective.
Regards,
Mileta -
Well I hope I'm not the only one who thinks these are BAD ideas[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 13 2003 08:55 EDT
- in response to Mileta Cekovic
Java is going down the C# path...
> What is wrong with borrowing good things from C# ? At the end, C# borrowed
>much more from Java.
I didn't say stealing from C# was wrong. I said we are making the same mistakes.
IMO C# is bloated and unreadable, just as bad as C++ only newer.
> > 1. ENUM's are the absolute worst. They make my blood boil and every
> > programmer I see using them (in C++ as well) is fired on the spot.
> > Programmers who try to use ENUM "alternatives" such as small classes
> > or interger constants will never get promoted and need serious help
> > in understanding object oriented design. No OO language needs ENUM's.
>
> And what about thousands of enum-like integer constants in Java libraries ?
>How would you replace them or how would you redesing public interfaces of these
>Java libraries to avoid them ?
The people who wrote these API's did a bad job IMO.
However I have to use Calendar, JOptionPane etc...
I am not the only one who thinks Calendar should be rewriten since it is
particularly bad, but I don't say it about every use of ENUM like structures.
I think that we should use what works to a reasonable extent.
I don't think we should supply another tool strictly because people choose to
write none object oriented code. Might as well add support for functions
and goto.
> > 2. Generics are just plain wrong, and even worse in the way they
> > are implemented. Did you know that it is still possible to get a
> > ClassCastException (or equivalent) when using generics in Java?
> >Generics is simply a different syntax for writing a cast, I think
> > programmers should be aware of what the language/VM is doing.
>
> And how would you implement generics (the so wanted feature by many, many Java
>programmers) into Java language by not breaking byte code compatibility with
>older VMs ? Do you have better idea ?
Yes. Don't.
I don't think generics are needed in dynamic languages. While templates are
useful generics are here simply to avoid a cast because all of us of the
former C++ crowd were tought that a cast is bad (because RTTI didn't exist
and when it did it was excensive).
Please read my other postings as to why generics don't solve much, and I
definetly object to adding generics without a usability study that PROVES that
they are useful.
Other than that I share an opinion with some pro generic folk that simply say
that there should be a shift. There should be a new language based on the
Java ideas (call it JavaNG) that has very similar API's, but no deprecated
methods, no AWT, cleaner IO and immutable date. In this language you can
implement generics from scratch without compatability issues. Since the
languages would be very similar the source code for the VM can be unified and
probably some of the libraries.
Why is everyone in such a hurry to patch Java badly, we're doing fine without
generics for the past 6/7 years....
> > 3. Autoboxing again is here to cut down on typing...
> > 4. Why add static imports is beyond me.
> > Every SINGLE one of these features offers NO benefit whatsoever
> > to the language neither in performance nor in readability or
> > maintainance (every benefit gained in readability is offset
> > by the fact that your reading something that isn't realated
> > to whats really happening).
>
> Saying that this changes do not improve readibility of Java language is at
>least not objective.
I never claimed to be objective, I am a manager/developer/consultant that has
to deal with these things every day.
The problem with static imports is that they make the benefit of encapsulation
harder to leverage:
When I see a block of code that contains:
methodName();
and I want to understand this methodName(). All I have to do is Ctrl-F and look
through the file. If the method isn't there its in one of the base classes.
With static imports I need to start digging in more classes (don't think people
won't statically import everything). One of the main problems we had in C++
was when someone defined in some header a small macro with a generic name
such as find(). Try to search through a million lines of code for a global
function with that name. Everything is simple until its scaled up to really
large projects where it becomes unmanageable. -
Well I hope I'm not the only one who thinks these are BAD ideas[ Go to top ]
- Posted by: Valentin Sliouniaev
- Posted on: April 13 2003 09:39 EDT
- in response to Shai Almog
I don't think we should supply another tool
> strictly because people choose to write
> none object oriented code. Might as well
> add support for functions and goto.
Ironically, staeless session ejbeans (the only ones to use i am told) look a lot like non-object-oriented functions to me, even though they are herded in groups. Come on, I had structures (value objects) and methods to pass them into (EJB services) in plain C twenty years ago, and RPC instead of SOAP. Aren't be busying ourselves not knowing on what to spend CPU cycles and network bandwidth? :-)
--VS. -
Well I hope I'm not the only one who thinks these are BAD ideas[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 13 2003 14:08 EDT
- in response to Valentin Sliouniaev
I don't think we should supply another tool
> > strictly because people choose to write
> > none object oriented code. Might as well
> > add support for functions and goto.
>
> Ironically, staeless session ejbeans (the only ones to use i am told) look a lot
>like non-object-oriented functions to me, even though they are herded in groups.
>Come on, I had structures (value objects) and methods to pass them into (EJB
>services) in plain C twenty years ago, and RPC instead of SOAP. Aren't be busying
>ourselves not knowing on what to spend CPU cycles and network bandwidth? :-)
While yes, stateless session beans are a bit on the none OO side (they are
still objects and still use an object oriented API and have a bit of container
state).
You don't even need to wander into EJB's to get this approach, you can go to
the servlet API as well....
Whatever works best IMO. -
Voting against RFE's[ Go to top ]
- Posted by: Luc Peerdeman
- Posted on: April 11 2003 05:21 EDT
- in response to Shai Almog
Shai Almog wrote:
> Every SINGLE one of these features offers NO benefit whatsoever
> to the language neither in performance nor in readability or
> maintainance (every benefit gained in readability is offset
> by the fact that your reading something that isn't realated
> to whats really happening).
Good point !
One of the reasons C++ did not appeal to me at all and Java did was the unnecessary complexity of the language. But I have noticed that many people actually _like_ unnecessary complexity, as it gives them an opportunity to show of their language expertise !
> I only wish that there was a way to vote against RFE's in the
> sun bug parade.
And I wish Arthur van Hoff would still be around at Sun to stop this seemingly inevitable pollution of the Java language (before Java came out he managed to keep out quite a few of these so called improvements as well).
Cheers, Luc. -
Re: BAD ideas[ Go to top ]
- Posted by: David Hamilton
- Posted on: April 11 2003 05:35 EDT
- in response to Shai Almog
Firstly, I would like to say that entirely agree with your comments about simplicity... that is to me a key attribute of Java, and one that Sun should strive to maintain.
However...
> 1. ENUM's are the absolute worst.
Why is it so bad to have a small number of known possible values for a type. What is your proposed alternative?
> 2. Generics are just plain wrong.
I have trouble understanding what is plain wrong about something that improves type safety for collections. Yes, there are still situations where class-cast exceptions can occur, but they are much reduced.
The important thing to note is that incorrect types will never be able to be added to a typed collection, which is an order on magnitude better than the current situation where you only find an error when you try to get the object out.
Have you ever tried figuring out which piece of code was responsible for adding an incorrect type to a collection - no fun at all, I can assure you. Assertions can help (for those who use 1.4).
As an aside, why, why, why did Sun not make the 1.4 compiler just strip out assertions when it is being run in 1.3 'mode', rather than refusing to compile the assertions? Extremely unhelpful.
Did you know that it is still possible to get a
ClassCastException (or equivalent) when using generics in Java?
Which circumstance did you have in mind?
>3. Autoboxing again is here to cut down on typing.
I was initially opposed to autoboxing, having seen some articles about issues with it in C#, but when I investigated further, they were due to extra features in C# that do not exist in Java. At the end of the day, as long as both the programmer and the compiler are clear about what is the effect of a piece of code, is it bad to reduce verbosity?
>4. Why add static imports is beyond me.
Agreed. Think the cost in potential abiguity at least matches the gain in improving terseness.
/david -
Re: BAD ideas[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 13 2003 09:17 EDT
- in response to David Hamilton
Firstly, I would like to say that entirely agree with your comments about
>simplicity... that is to me a key attribute of Java, and one that Sun should
>strive to maintain.
Good.
> However...
>
> > 1. ENUM's are the absolute worst.
>
> Why is it so bad to have a small number of known possible values for a type.
> What is your proposed alternative?
Please take a look at my other comments, its not the type safety I'm against
but the very existance of this outdated concept of hardcoding all the
posibilities. We use databases and encapsulation to provide this functionality
better (as in faster, with dynamic implementation and more elegant code).
> > 2. Generics are just plain wrong.
>
> I have trouble understanding what is plain wrong about something that improves
>type safety for collections. Yes, there are still situations where class-cast
>exceptions can occur, but they are much reduced.
The implementation is problematic (if you will follow my other posts).
And they simplify the simple while doing nothing regarding the reall
problems.
Templates are useful in C++ but generics arn't templates and neither one is
really needed in Java which is a dynamic language.
> The important thing to note is that incorrect types will never be able to be
>added to a typed collection, which is an order on magnitude better than the
>current situation where you only find an error when you try to get the object
>out.
This isn't true. You will be able to add untyped data and you will get class
cast exception when linking against binary classes.
This will simplify whats really simple like a collection of Strings/Numbers,
and this really isn't necessary. It will leave everything else complicated
(collections of Polymorphic objects).
> Have you ever tried figuring out which piece of code was responsible for
>adding an incorrect type to a collection - no fun at all, I can assure you.
>Assertions can help (for those who use 1.4).
Surprise I voted for assertions.
They were a small impact and they provide a great benefit. Generics are a
very large impact, they will be forced upon people who don't want to use
them (if an API returns a generic collection you have no choice). And they
won't work correctly. The very minor benefit of dubiously simplifying simple
collections (while making the syntax awkward) isn't worth it.
The only reason this got this far is because C# has it.
> Did you know that it is still possible to get a
> ClassCastException (or equivalent) when using generics in Java?
>
> Which circumstance did you have in mind?
I gave an example. Every generic collection can be cast to a none generic
collection for compatability so we can pass it into a method that doesn't
work with generics (probably older code) in which case that method may modify
the collection in an illegal way causing great confusion to the user.
> >3. Autoboxing again is here to cut down on typing.
>
> I was initially opposed to autoboxing, having seen some articles about issues
>with it in C#, but when I investigated further, they were due to extra features
>in C# that do not exist in Java. At the end of the day, as long as both the
>programmer and the compiler are clear about what is the effect of a piece of
>code, is it bad to reduce verbosity?
Yes, to some degree. I don't think people are clear about those things.
In C++ constructors and cast operators will be invoked invisibly just as the
compiler bends over backwards to try to do what it thinks you want.
This caused no end of debugging.
I very much oppose the idea of a compiler deciding it knows what I mean, this
might cost me a little bit of typing. But the advantage is that beginners will
maintain the understanding of the separation between the primitives and the
Objects which is crucial to understanding Java and its performance. -
Re: BAD ideas[ Go to top ]
- Posted by: David Hamilton
- Posted on: April 14 2003 08:30 EDT
- in response to Shai Almog
but the very existance of this outdated concept of hardcoding all the
posibilities. We use databases and encapsulation to provide this functionality
better (as in faster, with dynamic implementation and more elegant code).
Oh yes - we tried holding possibilities in a DB. Just ended up having to duplicate some of the state possibilities into the code where decision making is required on options in the DB.
So you end up with code/DB duplication, which need to be enforced/tested using Unit Tests.
The issue is that the world is imperfect - subclassing for all required types restricts dynamicism, storing in the DB restricts static decision making. Two forces pulling in opposite directions, with no easy compromise.
There may be scope in dynamically writing subtypes at runtime using the DB data, but then statically overriding general operation for specific types (either using equality, instanceof or overriding polymorphic methods) remains highly problematic.
This isn't true. You will be able to add untyped data and you will get class
cast exception when linking against binary classes.
Your issues are all based around linking types collections with legacy libraries. However, if there is a type expectation in the libraries that isn't documented, then the libraries are broken anyway - that is nothing to do with generics.
I really think you are mis-attributing the problem here....
It will leave everything else complicated
(collections of Polymorphic objects).
If you are storing objects in a typed collection where you are relying on object being subclasses (having more information), then you are breaking polymorphism.
The whole point about polymorphism is that all of the objects should be interchangable - if I create a LinkedList<Number> collection, and then subsequently rely on casting an object from that collection to an Integer to use Integer specific features then I am breaking polymorphism...
...specifically, I am writing stupid code and am looking to create problems for myself.
Surprise I voted for assertions.
To be blunt - I would have grave concerns about your judgement had you voted against ;-)
/david -
Generics[ Go to top ]
- Posted by: Brian Sayatovic
- Posted on: April 15 2003 09:21 EDT
- in response to David Hamilton
Regarding Generics, I've implemented type-safe containers by simply subclassing a List and overring the appropriate methods to check the type of the Object being added, and added convenience methods to get a type-casted return type on retrieval functions. This becomes more difficult, but not impossible, to extend to its Iterators and so forth.
The issue at hand is not that it is a new capacility in the language, but that it speeds up the work. Developers will no longer have to implement such type-safe Collections on their own, nor rely on code-generators to do it for them.
However, these generics won't offer me the sort of parametric-polymorphism I've been drooling about since I read Tim Seeny's article on it years ago. I want to be able to subclass an entire framework, and override one of its constituent classes, and have all other inherited code refer to my new class instead of the old one. THAT would be power. -
Generics[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 15 2003 10:10 EDT
- in response to Brian Sayatovic
Regarding Generics, I've implemented type-safe containers by simply subclassing
>a List and overring the appropriate methods to check the type of the Object being
>added, and added convenience methods to get a type-casted return type on
>retrieval functions. This becomes more difficult, but not impossible, to extend
>to its Iterators and so forth.
Please read my other posts explaining both why generics won't work and why they
are redundant. The proposed implementation just doesn't work. -
Autoboxing[ Go to top ]
- Posted by: Brian Sayatovic
- Posted on: April 15 2003 09:22 EDT
- in response to David Hamilton
Regarding autboxing, one thing you gain (speed of development) is also a loss (loss of performance). This is not an absolute, but consider the case where you want to use int's as a key in a HashMap. Autoboxing would convert each int to an Integer, and internally, the HashMap could be calling .hashCode() and .equals() like mad. However, if someone wrote their own IntHashMap (which I've done), you would use the int itself as the hashcode, and use the equality operator instead of a .equals() method call. This would be quite a bit faster. But autoboxing will tend to obscure this difference at the surface. -
ClassCastExceptions on Generics[ Go to top ]
- Posted by: David Hamilton
- Posted on: April 11 2003 06:23 EDT
- in response to Shai Almog
Did you know that it is still possible to get a
ClassCastException (or equivalent) when using generics in Java?
Just double checked - trying to add an object of incorrect class to a 'typed' collection is caught by the compiler.
I can see that the generics implementation may still allow some ClassCastExceptions, but I am interested in what situations you envisage it happening.
/david -
JDK1.5 Features[ Go to top ]
- Posted by: Dean Sheppard
- Posted on: April 11 2003 08:26 EDT
- in response to David Hamilton
IMHO, I think that the inclusion of enums, and autoboxing are great features to be added to the java platform. -
Why add static imports ?[ Go to top ]
- Posted by: Maris Orbidans
- Posted on: April 11 2003 08:27 EDT
- in response to David Hamilton
what if two statically imported classes have methods with same name and signature ? I guess it would be impossible to do such import.... -
Handle it the same way[ Go to top ]
- Posted by: Brian Sayatovic
- Posted on: April 15 2003 09:26 EDT
- in response to Maris Orbidans
You have thats ame problem now if two packages have the same class name and you import them as .* -- however, there is a rule in the language specs which says that one import has precdence over the other. I can't remember which (is it the first or last?), but I recall encountering this myself years ago. That's why, with rare exception, I import every class exlicitly. These sorts of naming conflicts are much more apparent then, -
ClassCastExceptions on Generics[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 13 2003 09:24 EDT
- in response to David Hamilton
Did you know that it is still possible to get a
> ClassCastException (or equivalent) when using generics in Java?
>
> Just double checked - trying to add an object of incorrect class to a 'typed'
>collection is caught by the compiler.
>
> I can see that the generics implementation may still allow some
>ClassCastExceptions, but I am interested in what situations you envisage it
>happening.
Since generics maintain compatability you can call "none generic" code which
adds an element to your now "seemingly regular" collection. This will cause
an exception.
This isn't a rare use case, when people run into it they will look
for someone to hang from a flagpole since this is really not obvious
to people who don't understand how generics are implemented. -
ClassCastExceptions on Generics[ Go to top ]
- Posted by: David Hamilton
- Posted on: April 14 2003 11:29 EDT
- in response to Shai Almog
Shai wrote:
Since generics maintain compatability you can call "none generic" code which
adds an element to your now "seemingly regular" collection. This will cause
an exception.
Just tried calling the generic add on a subroutine that had been passed a 'typed' LinkedList. Got the following:
<pre>Note: mypack/Test.java uses unchecked operations.
Note: Recompile with -warnunchecked for details.</pre>
Ading the -warnunchecked flag yields the following:
<pre>mypack/Test.java:39: warning: unchecked call to add(E) as a member of the raw ty
pe java.util.LinkedList
list.add( new String("Bad!"));
^
</pre>
Also tried reassigning a standard collection to a 'typed' collection. Got:
<pre>mypack/Test.java:39: warning: unchecked assignment: java.util.LinkedList to java
.util.LinkedList<java.lang.String>
LinkedList<String> ys = list;
^
</pre>
Which looks to me as if they cover this as long as you don't ignore the warnings(!)
/david -
ClassCastExceptions on Generics[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 15 2003 01:33 EDT
- in response to David Hamilton
<pre>Note: mypack/Test.java uses unchecked operations.
> Note: Recompile with -warnunchecked for details.</pre>
>
> Ading the -warnunchecked flag yields the following:
A. You need to add a specific flag.
B. Large projects have a ton of warnings due to the liberal use
of deprections. If we want to maintain 1.3 compatability there
are some deprecated methods we need to use.
C. Reflections and most dynamic code won't provide any warnings.
D. Warnings are often ignored by the same people who will be bitten
the worse by this problem.
E. Warnings in Java appear only on rebuild and are very easily
missed and lost. The person compiling that code the first
time will see the warning and understand, the one who actually
runs into the problem will never see the warning!
F. If a library performs this type of cast for compatability or
due to a requirement we won't see any warning since the library
is binary.
Warnings should not be used in place of errors. What we have here
is an object that no longer respects its contract, thats an
error! -
ClassCastExceptions on Generics[ Go to top ]
- Posted by: David Hamilton
- Posted on: April 15 2003 06:40 EDT
- in response to Shai Almog
A. You need to add a specific flag.
Ermm, yes... and?
B. Large projects have a ton of warnings due to the liberal use
of deprections. If we want to maintain 1.3 compatability there
are some deprecated methods we need to use.
Use of a decent IDE would allow to control your warnings and have important ones flagged as errors.
C. Reflections and most dynamic code won't provide any warnings.
Yep, agreed. I have had a quick look at their proposed changes to reflection, but there don't seem to be an implementation in the generics examples.
Changes to reflection would be good, but would presuambly break backwards compatibility...
D. Warnings are often ignored by the same people who will be bitten
the worse by this problem.
I'm sorry - but if you ignore a warning and then are taken by surprise by an error that results from it, you're on your own...
... a long time ago I worked with someone who turned off all warnings (had a couple of thousand of them - didn't know what they meant - didn't care). His project collapsed under the weight of bugs.
E. Warnings in Java appear only on rebuild and are very easily
missed and lost. The person compiling that code the first
time will see the warning and understand, the one who actually
runs into the problem will never see the warning!
Use a decent IDE.
F. If a library performs this type of cast for compatability or
due to a requirement we won't see any warning since the library
is binary.
Yes. The important question though is 'What is the library doing to the collection'. If it is doing something that breaches the generics contract, that it is still breaching the unwritten contracts between the two pieces of code.
If your unit testing is as good as you say, that library should have already blown up your test! Or don't you have unit tests on these libraries? In which case, all you said about having unit tests that ensure that incorrect data can never be inserted into collections would be completely incorrect...
Warnings should not be used in place of errors. What we have here
is an object that no longer respects its contract, thats an
error!
Problem is (like you say) is backward compatibility for existing code. (Otherwise deprecated should be an error!)
/david -
ClassCastExceptions on Generics[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 15 2003 10:38 EDT
- in response to David Hamilton
A. You need to add a specific flag.
>
> Ermm, yes... and?
People will just ignor it. Just like deprecated methods etc... The problem is
that warnings aren't repeated in later compiles only rebuilds.
> B. Large projects have a ton of warnings due to the liberal use
> of deprections. If we want to maintain 1.3 compatability there
> are some deprecated methods we need to use.
>
> Use of a decent IDE would allow to control your warnings and have important
>ones flagged as errors.
Using Eclipse are we?
I myself don't use an IDE but most large projects would have a large amount of
warnings as I said and you develop a habit of somewhat ignoring them after some
point. Sure, when integration arrives you go through each one, but that might
be too late.
Anyway we are assuming highly confident developers who probably also know about
the way generics are implemented in Java... The problem will hurt the most the
relative newbies.
> C. Reflections and most dynamic code won't provide any warnings.
>
> Yep, agreed. I have had a quick look at their proposed changes to reflection,
>but there don't seem to be an implementation in the generics examples.
>
> Changes to reflection would be good, but would presuambly break backwards
>compatibility...
Nothing!! Is worth breaking compatability.
> D. Warnings are often ignored by the same people who will be bitten
> the worse by this problem.
>
> I'm sorry - but if you ignore a warning and then are taken by surprise by an
>error that results from it, you're on your own...
There is a convention in Java regrading what constitutes a warning and what
constitutes an error. Unlike C++ where warnings are up to the compiler vendor
in Java Sun was pretty clear that everything that causes "real" damage is an
error. The moment a contract is broken its an error, you can't place a long
into an int without explicitly saying so (in C thats a warning).
EVERY other warning in Java doesn't break anything! Deprecated methods work!
Everything works regardless. Up until now warnings were just general and Java
used errors for placing long into an int without a cast.
This is the first and AFAIK the only warning that will probably cause an
application to break (you can make an argument for Thread.stop() but that
should work as the API specifies).
People ignor warnings because they were never used for anything critical in
Java. Furthermore they will look at the warning and decide it is ok. Only later
will the problem appear (possibly to a different programmer) and by then the
warning would have been forgotten. I remember this exact scenario, from C++
and these are the exact problems that Java up until now avoided. While Java
has its warts it NEVER knowingly added a broken feature to begin with.
> ... a long time ago I worked with someone who turned off all warnings (had a
>couple of thousand of them - didn't know what they meant - didn't care). His
>project collapsed under the weight of bugs.
True, I am working on a project that has 30 (I'm linking external code that
needs to compile against some deprected servlet methods, don't ask ;)
anyway I doubt if I will notice 1 more or less and I usually notice these
things.
> E. Warnings in Java appear only on rebuild and are very easily
> missed and lost. The person compiling that code the first
> time will see the warning and understand, the one who actually
> runs into the problem will never see the warning!
>
> Use a decent IDE.
I'm guessing you use Eclipse, I can't stand it myself. I find its error handling
to be terrible. Anyway Java is a standard not an idea or a product, you can't
fix things by providing a GUI. Check out JBoss vs. the RI, JBoss is much
easier to use despite having no decent GUI while the GUI of the RI is just a
buggy mess (in J2EE 1.3).
> F. If a library performs this type of cast for compatability or
> due to a requirement we won't see any warning since the library
> is binary.
>
> Yes. The important question though is 'What is the library doing to the
>collection'. If it is doing something that breaches the generics contract,
>that it is still breaching the unwritten contracts between the two pieces of
>code.
Yes it is, but you don't have any control over the quality of the software
you get from vendors. Furthermore, it might be using an external library
itself or possibly extracting data from you via a callback. The possibilities
for unpredictable failure are endless.
When I get a class cast exception I get a specific line in which the failure
occured and I know the problem. With Generics I will get an exception from the
internals of a collection and possibly a third party vendor which I have no
clue of where to start.
> If your unit testing is as good as you say, that library should have already
>blown up your test! Or don't you have unit tests on these libraries? In which
>case, all you said about having unit tests that ensure that incorrect data can
>never be inserted into collections would be completely incorrect...
I said that it will solve simple cases not complex cases as the ones I
described. Yes I might have sounded a bit overconfident with that ;)
Anyway I'm not saying unit testing won't find this (it probably will) but then
we will have a much harder time finding the problem. I myself would probably
know what to do but I doubt most people would understand why a supposedly
type safe collection throws a ClassCastException?
> Warnings should not be used in place of errors. What we have here
> is an object that no longer respects its contract, thats an
> error!
>
> Problem is (like you say) is backward compatibility for existing code.
>(Otherwise deprecated should be an error!)
Huge difference, deprecated methods WORK and they work as close as possible to
the 1.0/1.1/1.2/1.3 impelementations. Collection casting doesn't work like
the collections that worked in 1.2/1.3/1.4.... -
ClassCastExceptions on Generics[ Go to top ]
- Posted by: David Hamilton
- Posted on: April 15 2003 11:19 EDT
- in response to Shai Almog
I'm guessing you use Eclipse, I can't stand it myself. I find its error handling to be terrible.
OK, I'll bite - terrible error handling? Go on, I'm intrigued...
When I get a class cast exception I get a specific line in which the failure
occured and I know the problem.
Yes - the problem is that your system and the library are working to different contract specifications!
At the end of the day - if the data coming out of the library is as bad as you say, I would treat it as an external data source and add a validation/cleansing layer before attempting to work with the data.
With Generics I will get an exception from the
internals of a collection and possibly a third party vendor which I have no
clue of where to start.
Clear the innocent and punish the guilty!! It would be a terrible situation knowing which line is was that was actually responsible for the problem! ;-)
Thing is, you seem to think that by not having generics, it cures the problem - it doesn't. It just moves it somewhere else....
> Problem is (like you say) is backward compatibility for existing code.
>(Otherwise deprecated should be an error!)
Huge difference, deprecated methods WORK and they work as close as possible to
the 1.0/1.1/1.2/1.3 impelementations. Collection casting doesn't work like
the collections that worked in 1.2/1.3/1.4....
Officially deprecated says 'All bets are off... this may or may not work'. Yes, they may still work, but the contract that says they have to is no longer there.
I've encountered one issue with a feature from 1.0 that was deprecated breaking in 1.4 (closed - will not fix). Think it was ID 4624678, but I can't check, as the bugbase is not serving documents at the moment.
And the generics warning only indicates that the code might not work, and to check closely as to whether it will or not....
/david -
ClassCastExceptions on Generics[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 15 2003 13:04 EDT
- in response to David Hamilton
I'm guessing you use Eclipse, I can't stand it myself. I find its error
>handling to be terrible.
>
> OK, I'll bite - terrible error handling? Go on, I'm intrigued...
Well its a matter of taste, I used WSAD quite a bit for an IBM project and
the concept of errors where you see all errors and warning for the project
and the deployed code (which BTW has warnings in it that you should ignor)
was simply impossible for me. Maybe I need to get used to their way of doing
things but I doubt I'll ever be able to.
While I used IDE's very extensively in the past, their features today can't
keep up with my needs. Only the fastest IDE's have autocomplete which comes
close to be useful (with my typing speed) and other than that they generally
hold me back. Its nice to deploy with a right click but they actually make
code maintainance harder (since they generate code once and then try in
vain to keep it in sync).
Anyway I digress, the point I was making is that we can't rely on IDE's to
handle language level features and fix something thats broken. Please no
flame on this (since its a bit offtopic): especially not with the sorry crop of
current Java IDE's.
> When I get a class cast exception I get a specific line in which the failure
> occured and I know the problem.
>
> Yes - the problem is that your system and the library are working to different
> contract specifications!
>
> At the end of the day - if the data coming out of the library is as bad as you
>say, I would treat it as an external data source and add a validation/cleansing
>layer before attempting to work with the data.
The libraries code isn't necessarily bad, just different. And why should we
build compatability layers for code written in Java. If you do that then
you might as well give up on the whole downcast and settle for generics that
are not downcastable.
> With Generics I will get an exception from the
> internals of a collection and possibly a third party vendor which I have no
> clue of where to start.
>
> Clear the innocent and punish the guilty!! It would be a terrible situation
>knowing which line is was that was actually responsible for the problem! ;-)
Yes, I'm willing to forgive bad coding and broken contracts when it comes
to an API implementation since that isn't a sweeping change that will break
everything and be forced on people.
I am not willing to accept that type of breakage in the language level.
Big difference, a bad API/Library is fixable/replaceable.
> Thing is, you seem to think that by not having generics, it cures the problem
>- it doesn't. It just moves it somewhere else....
Sorry if I said that, I don't deny the existance of the problem generics means
to solve. I said two distinct things:
1. Generics is slightly effective in the simple problems only and for so little
a difference it isn't really necessary (this is debatable).
2. Generics can't be backwards compatible and the current implementation is
broken (this is a fact). I think this warrants either stopping the current
JSR completely or at least rewriting it so generic classes cant be cast to their
none generic counterpart.
You could use special wrapper objects to simulate the casting behaviour, and the
JIT could know about them and optimize them away. This will allow both 100%
compatability and will eliminate the problem we have.
ClassCastException
java.util.Collection<Integer>...
java.util.CollectionWrapper
....
Just brainstorming here but how come this didn't come up in the JSR.
> > Problem is (like you say) is backward compatibility for existing code.
> >(Otherwise deprecated should be an error!)
>
> Huge difference, deprecated methods WORK and they work as close as possible to
> the 1.0/1.1/1.2/1.3 impelementations. Collection casting doesn't work like
> the collections that worked in 1.2/1.3/1.4....
>
> Officially deprecated says 'All bets are off... this may or may not work'.
>Yes, they may still work, but the contract that says they have to is no longer
>there.
The moment this happens I bet Sun will turn that specific deprecation into an
error. If not I will be the first one yellig foul.
Its not that I care much about methods that were deprecated in 1.0 but
I definetly need the strong distinction Java has between errors and warnings
(as it has between types).
> I've encountered one issue with a feature from 1.0 that was deprecated
>breaking in 1.4 (closed - will not fix). Think it was ID 4624678, but I can't
>check, as the bugbase is not serving documents at the moment.
>
> And the generics warning only indicates that the code might not work,
>and to check closely as to whether it will or not....
This is really bad, do you remeber the specific method/feature and the reason
they gave. Some internal behaviour can't be simulated 100% which is
understandable.
Anyway this still isn't as bad as the generics issue since as I said, even
the API is a library (the most important one yes) but generics are a change
to the language. Thats a much bigger deal. -
ClassCastExceptions on Generics[ Go to top ]
- Posted by: Robert Devi
- Posted on: April 15 2003 14:38 EDT
- in response to Shai Almog
Generics can't be backwards compatible and the current implementation is
> broken (this is a fact). I think this warrants either stopping the current
> JSR completely or at least rewriting it so generic classes cant be cast to
> their none generic counterpart.
Essentially, your key objection is that generics aren't strict enough. Many people have the same complaint about exceptions in C++. In C++, by default, a function may throw any exception. This semantics was defined for mostly backwards compatibility reasons since most functions were designed without exceptions in mind. The key motivator for the current definition of generics is similar.
Ideally, you'd want to make all classes declare all exceptions that they use, but practically this is problematic because any method can throw a run-time exception so all methods would need to declare at least one exception. Java solved this issue by silently declaring that all children of RuntimeException are implicitly thrown by all methods.
Java gives you the choice as to how strict you want your exception prototypes to be. Why can't it do the same for generics?
Essentially, I'm proposing that
class Foo<T> { .... }
be strict by default, meaning that Foo<T> is not automatically converted to Foo<Object> or Foo. New generics code would likely use this format since you wouldn't have to worry about interacting with legacy code.
However, if you wanted an automatic conversion because Foo<T> needs to interact with legacy libraries that know nothing of generics, you'd add it to the declaration:
class Foo<default T> { ... }
or
class Foo<T=Object> { ... }
or
class Foo<T->Object> { ... }
or
class Foo<autoconvert T> { ... }
if you're willing to add an extra keyword.
The standard collection classes would be declared to be
Right now, List<T> is automatically converted to List as it is needed because otherwise it would require that all Java libraries (including the Swing and EJB libraries) be adapted to templates. However, there's no reason why a StrictCollection template library couldn't be created that followed strict template typing with no auto-convert. -
ClassCastExceptions on Generics[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 16 2003 01:17 EDT
- in response to Robert Devi
Generics can't be backwards compatible and the current implementation is
> > broken (this is a fact). I think this warrants either stopping the current
> > JSR completely or at least rewriting it so generic classes cant be cast to
> > their none generic counterpart.
>
> Essentially, your key objection is that generics aren't strict enough. Many
>people have the same complaint about exceptions in C++. In C++, by default, a
>function may throw any exception. This semantics was defined for mostly
>backwards compatibility reasons since most functions were designed without
>exceptions in mind. The key motivator for the current definition of generics is
>similar.
No.
Thats not my complaint.
I repeated it enough times already:
1. Broken (can be fixed by making stricter)
2. Unnecessary (Matter of opinion, can't be fixed).
Hardly anyone defined anything in C++ for backwards compatability... They moved
the whole thing into the std:: namespace and made some ridiculous changes.
But I don't think this example is similar
The reason they chose to do it this way was to avoid incompatible byte code.
However there is no other choice.
If you look at the problem with generics it will occur at most when people try
to use it under older VM's usually in closed libraries, by forcing genrics to
be used ONLY in 1.5+ environments adoption will be slower (people waited long
enough they can wait a bit longer to get a WORKING implementation) but
they won't fail (ever!)
Furthermore generics will be implemented correctly as objects on their own
which is consistent with Java arrays being objects.
> Ideally, you'd want to make all classes declare all exceptions that they use,
>but practically this is problematic because any method can throw a run-time
>exception so all methods would need to declare at least one exception. Java
>solved this issue by silently declaring that all children of RuntimeException
>are implicitly thrown by all methods.
This example is incorrect.
It assumes all I want is strictness, when what I want is language consistency.
Why would I want strictness for a feature I don't care for and plan to avoid
as much as possible?
> Java gives you the choice as to how strict you want your exception prototypes
>to be. Why can't it do the same for generics?
No it doesn't. If a method throws a declared exception you HAVE to catch or
throw that exception. If you throw your own within your own API implementation
thats fine.
Anyway still offtopic.
> Essentially, I'm proposing that
> class Foo<T> { .... }
> be strict by default, meaning that Foo<T> is not automatically converted to
>Foo<Object> or Foo. New generics code would likely use this format since you
>wouldn't have to worry about interacting with legacy code.
Thats a suggestion, but I have a problem with the whole idea of tainting all
"the old code". This should be a strict 1.5+ solution and should never allow
downcasting.
I couldn't care less about how generics are written since I don't intend
to use them myself, I care about the ways in which they might break my
applications.
> However, if you wanted an automatic conversion because Foo<T> needs to
>interact with legacy libraries that know nothing of generics, you'd add it to
>the declaration:
> class Foo<default T> { ... }
> or
> class Foo<T=Object> { ... }
> or
> class Foo<T->Object> { ... }
> or
> class Foo<autoconvert T> { ... }
> if you're willing to add an extra keyword.
Adding a keyword (with a compiler switch to turn it on) is legitimate although
again further clutter to a clean language.
Anyway as I said, I don't really care about this aspect of the implementation
since there are many options that don't break compatability.
Anyway this looks like the hellish template code to me.
> The standard collection classes would be declared to be
> Right now, List<T> is automatically converted to List as it is needed because
>otherwise it would require that all Java libraries (including the Swing and EJB
>libraries) be adapted to templates. However, there's no reason why a
>StrictCollection template library couldn't be created that followed strict
>template typing with no auto-convert.
You will need to adapt all libraries anyway. Might as well do it right and make
sure the vendors of the libraries did it right. -
ClassCastExceptions on Generics[ Go to top ]
- Posted by: David Hamilton
- Posted on: April 16 2003 04:22 EDT
- in response to Shai Almog
>Well its a matter of taste, I used WSAD quite a bit for an IBM project and
>the concept of errors where you see all errors and warning for the project
>and the deployed code (which BTW has warnings in it that you should ignor)
>was simply impossible for me. Maybe I need to get used to their way of doing
>things but I doubt I'll ever be able to.
Eclipse does provide a lot of control about how a number of warnings (and sometimes errors) can be treated. It also gives quite a lot of control over what shows up in the tasks list.
>> At the end of the day - if the data coming out of the library is as bad as you
>>say, I would treat it as an external data source and add a validation/cleansing
>>layer before attempting to work with the data.
>The libraries code isn't necessarily bad, just different.
Aaaaaarrrggghhhh!!! That's the whole point: If the libraries are doing something different (like adding objects that are outside the range of object that you are expecting), then you should either be cleansing out the rogue objects before the collection is allowed loose into your system, or not using the library.
/david -
ClassCastExceptions on Generics[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 16 2003 06:15 EDT
- in response to David Hamilton
Eclipse does provide a lot of control about how a number of warnings (and
>sometimes errors) can be treated. It also gives quite a lot of control over
>what shows up in the tasks list.
It does, I guess its a matter of taste. I was never able to use Emacs and to
me Eclipse looks roughly the same (overly complex). I also never really liked
the approach of Visual Studio which Eclipse seems to emulate to some degree.
> >> At the end of the day - if the data coming out of the library is as bad as you
> >>say, I would treat it as an external data source and add a validation/cleansing
> >>layer before attempting to work with the data.
>
> >The libraries code isn't necessarily bad, just different.
>
> Aaaaaarrrggghhhh!!! That's the whole point: If the libraries are doing
>something different (like adding objects that are outside the range of object
>that you are expecting), then you should either be cleansing out the rogue
>objects before the collection is allowed loose into your system, or not using
>the library.
This isn't really an option always. Anyway I think this thread is dead since
whether the library should be removed or proxied is not really the point of the
discussion.
I think the points I was aiming for and ones we can agree on is:
a. Problems will occur, since the way generics does things is different than
the older way.
b. It might prove very difficult to most programmers to understand the resulting
problem triggered by the generics implementation. Rather than solve the problem
some of them will simply workaround it without understanding what went wrong
blaiming the bug on the library/VM.
c. In some cases the fix might not be either elegant or simple. While we gave
a relatively simple example there might be a case where the library vendor is
right to add a different type (in a case of a polimorphic object). -
Well I hope I'm not the only one who thinks these are BAD ideas[ Go to top ]
- Posted by: Joshua Y
- Posted on: April 11 2003 11:18 EDT
- in response to Shai Almog
Simply saying, I agree on your point.
I can't judge how each single feaure would have impact on the future the
language. Maybe, they won't do any harm.
My belief is that whatever new features should not scare off
new comers as well as existing users. Nobody can't deny
simplicity was one of the strongest points behind the trendmendous
success of Java. Programming is not a hobby of technical geeks any
more, as you all know. Java should maintain its position as simple
and powerful enough for mixed groups of novice and experts.
The complexity of the software has grown for years, the languahge
should not add much more complexity to it. Unfortunately, I am not
at the point that I can make sound judges for the sake of Java
in all sides without technical bias. I hope people in the leadership
positions would do. One thing I want to say to them is that opnions
in this board mostly from people proud of their technical supremacy
do not account for all levels of Java users including the prospects. -
Well I hope I'm not the only one who thinks these are BAD ideas[ Go to top ]
- Posted by: Tero Vaananen
- Posted on: April 11 2003 11:43 EDT
- in response to Shai Almog
Shai Almog:
> 1. ENUM's are the absolute worst.
Let's see:
public void foo(int myenum);
Tell me what values I should use in myenum so I get correct behaviour? The method is not documented so I don't know. When you have an answer for me, I accept your argument that enums are the absolute worst.
>
> 2. Generics are just plain wrong, and even worse in the way they
> are implemented.
Let's see:
public Collection getFoo();
Tell me what type objects should I expect from the collection returned from this method. The method is not documented so I don't know. When you have an answer for me, I accept your argument that generics are plain wrong. Right now Java has the "poor man's" generics where everything is Object. Cool.
> Every SINGLE one of these features offers NO benefit whatsoever
> to the language neither in performance nor in readability or
> maintainance (every benefit gained in readability is offset
> by the fact that your reading something that isn't realated
> to whats really happening).
So you are saying that my examples are perfectly good for readability and maintenace? Good luck.
--
Tero -
Well I hope I'm not the only one who thinks these are BAD ideas[ Go to top ]
- Posted by: Joshua Y
- Posted on: April 11 2003 13:44 EDT
- in response to Tero Vaananen
I think it is deveopers responsibilities to produce cleaner
codes, not the language features. Seasoned developers first
get a grasp of the limitations and best practices for
the language. Your example is actually an example of short-sigted
programmers's mistake not the lack of language features.
What Generic-haters here argue is, I think, that keeping
the complexity in check is the best way to reduce such a
misuse of the language. Many ppl cry for usefulness of generics
and enums. Those features are quite useful and powerful
when applied appropriately.
However, many of usefulness come from the situations that were
created in a mind set fixed from other langauges. If such features
are absolutely needed, then there are so many other languages
on the shelf. Java has been powerful enough in most cases Java
has thrived. Even though I dont believe
couple of new features would falter the langauge in the near future,
if Java is evolved in a way that starts to satisfy all of advancing
feaures of Ph.D papers, it wouldn't be able to avoid the path of C++.
I think Java is just a fine language that is obivous enough for
the new comers to not take years to learn and simple enough to
write the system of millions lines of codes and stupid enough to just
do basic information processing. Isn't that what Java is for??? -
Well I hope I'm not the only one who thinks these are BAD ideas[ Go to top ]
- Posted by: Robert Devi
- Posted on: April 11 2003 15:21 EDT
- in response to Joshua Y
I think it is deveopers responsibilities to produce cleaner
> codes, not the language features.
Agreed to a certain extent. We need to ensure that the language does not grow unnecessarily since each feature has a cost in terms of language complexity, learning time, and ambiguity. C++ has several grey areas where only language nazis can predict the result (look at some of the obfuscated C++ contests). If you have to spend more than 1-2 seconds trying to understand a line of code, the language is too complex for large projects. Maintenance, which requires a lot or re-reading the code, just takes too long.
However, if language simplicity and the costs of adding features were the only factors that were important, we'd be all be programming assembly language. Who needs types when untyped words can do the job? Who needs variables when registries, stacks, and heaps? You can write a full J2EE application in JVM, especially if you have a JVM macro language like they do for normal assembly language. It's definitely simpler and more well defined than Java. Anything you can do in Java, you can do in the JVM. In fact, I'm willing to bet you could do more in the JVM than Java.
Java is just syntactic sugar for patterns of JVM code. So why use Java? Simply because JVM code is too flexible so it's easier to be error-prone when programming JVM code. It also doesn't encapsulate the higher level patterns (e.g. for loop, method, inner class, etc) so programmers need to spend more time understanding the same amount of functionality. We need to take both the costs and benefits into account.
Metadata, foreach, static import, enum and generics are just syntactic sugar. They each encapsulate popular Java patterns.
Foreach, static imports, and enums are extremely easy to learn, add almost nothing to the language complexity or ambiguity. This minimal cost needs to be weighed against the benefits. Static imports get rid of the common incorrect pattern of inheritence of constants (i.e. If MyClass needs several constants from Constants, inheriting MyClass from Constants means that MyClass ISA Constants.). Foreach and enums reduce reduce the writing of error prone code. Is the benefit worth the (small) cost? That's debatable (I think some form of enum is). My only concern is that with the current implementation of enums is how it interacts with EJBs. If enums were simple integers, there would be no problems since integers are passed by value, but since enums are classes, there may be a few class-identity issues.
Metadata is something that adds little complexity to the language but it's impossible to understand without knowing the context of the usage (i.e. the same tag can mean many things). To evaluate it, it needs to be compared with technology patterns it's trying to replace (e.g. 3 EJB classes for one implementation class and information in the deployment descriptor) to see if there are any real benefits. Anecdotal evidence from XDoclet (it's closest cousin) seems to indicate that it may be worth the cost, so the only question is whether it's better to incorportate Metadata into the language as a language extension, incorporate it in the J2EE library/tools spec, or let 3rd part tools like XDoclet handle the feature.
Generics, under the current implementation, are fairly restricted, easy to understand, and interact well with legacy libraries (e.g. a List<T> can be passed to a method that expects a List). They reduce the need for casting, provide more documentation on the usage of collections, reduce the number of classes you need, and reduce the error-prone case where you add the wrong data-type to a collection. If my experience with C++ is any indication, errors messages in templated code tend to be more cryptic, although using templated code tends to be simpler and easier to explain. Is this feature worth the price? I definitely think it's worth it for the standard library collections, but whether it's worth it for general purpose programming is debatable. I'm a bit concerned, again, how generics interact with EJB code. What happens if you say your method passes or returns a generic? -
"JVM Code"[ Go to top ]
- Posted by: Toby Reyelts
- Posted on: April 11 2003 16:38 EDT
- in response to Robert Devi
Java is just syntactic sugar for patterns of JVM code. So why use Java? Simply because JVM code is too flexible so it's easier to be error-prone when programming JVM code. It also doesn't encapsulate the higher level patterns (e.g. for loop, method, inner class, etc) so programmers need to spend more time understanding the same amount of functionality.
---
I understand the point you're trying to make, but the statements you're using to try to make that point are false. The JVM spec explicitly specifies inner classes and methods, and the bytecode for while and for loops is so simple and predictable that any decompiler can very easily detect and 'reverse engineer' them. This is one of the characteristics that separates the JVM from many other computing machines. Its primitives operate at a much higher level of abstraction.
Aside from all that, pretty much every addition to the language that we're seeing in Tiger is just a small amount of syntactic sugar - even Java Generics. All of the changes, combined, make a small contribution to the improvement of the type system. I'll be nice and save my raves and rants on the weakness of Java Generics for another day.
God bless,
-Toby Reyelts -
Grey areas[ Go to top ]
- Posted by: Valentin Sliouniaev
- Posted on: April 11 2003 16:46 EDT
- in response to Robert Devi
Well said!
Some comments:
>>> "We need to ensure that the language does not grow unnecessarily since each feature has a cost in terms of language complexity, learning time, and ambiguity. "
If it isn't in the language, it is in J2EE and WAR descriptors.
There's no way to ignore complexity. It is however often possible to express it in more simple terms, hiding repetitive details (patterns). One file instead of two or three or... five (.java with attributes), a pictute (a live UML diagram auto-generated from source), a set of Java classes auto-generated from an XML schema, a cool class loader, injecting code in each method for profiling / tracing / J2EE (COM+, originally) interception.
Truly, finding these patterns and collapsing them into a robust construct is a way to combat complexity. Only I doubt that a single language can do it. At a certain level, Java itself becomes too low-level. Examples include Castor, JSP, UML (Together J), Web Services orchestration (BizTalk).
>>> "C++ has several grey areas where only language nazis can predict the result (look at some of the obfuscated C++ contests).
Java has its "finer" areas, too: enum little classes misgehaving in J2EE servers is one, hashCode-equals pair in HashMaps, etc. is another, not to mention data synchronisation on SMP machines.
Why should we all stick to improving an average model of a pedal car (granted, safe for everyone) but never think of designing a bike and a jet, too. (JIT isn't jet, BTW :-))
Well, I wrote is as a joke, but doesn't jit look like a fine piece of overengineering? Java now is primarily used on servers. Why not pre-compile byte codes once (similar to rmi stubs)? Then the whole jit runtime "database" can be disposed of, and the compiled code loaded as shared for all processes. The runtime library would be the first candidate for compilation, at the time when jdk or jvm is installed. (Guess who already does this?).
regards,
--VS. -
Well I hope I'm not the only one who thinks these are BAD ideas[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 11 2003 17:36 EDT
- in response to Robert Devi
However, if language simplicity and the costs of adding features were the only
>factors that were important, we'd be all be programming assembly language. Who
>needs types when untyped words can do the job? Who needs variables when
>registries, stacks, and heaps? You can write a full J2EE application in JVM,
>especially if you have a JVM macro language like they do for normal assembly
>language. It's definitely simpler and more well defined than Java. Anything you
>can do in Java, you can do in the JVM. In fact, I'm willing to bet you could do
>more in the JVM than Java.
Robert,
we agree on that, so no offence but there is no need to be cynical ;)
Anyway my point is that Java is very successful in part due to its simplicity.
By adding features that both clutter the language and CANNOT BE AVOIDED by
those of us who don't want them (since they will be used by API's we need)
well... I would personally feel dissapointed (I really don't want to use
the word betrayed here since Sun usually listens to its customers and ISV's).
> Java is just syntactic sugar for patterns of JVM code. So why use Java? Simply
>because JVM code is too flexible so it's easier to be error-prone when
>programming JVM code. It also doesn't encapsulate the higher level patterns
>(e.g. for loop, method, inner class, etc) so programmers need to spend more
>time understanding the same amount of functionality. We need to take both the
>costs and benefits into account.
I myself hardly ever get class cast exceptions of the type generics solve.
I suggest everyone here writes down all of these cases in which you got such
an exception. You will see that these cases occur when you use polymorphic
collections, and this won't be solved by generics.
People expect great changes for genrics but frankly generics will make the
really easy things (single type collections) very slightly simpler, while
not making a difference to the complicated things (polimorphic collections).
Furthermore the fact that a compatible implementation that actually works
is technically impossible adds a level of complexity that makes the change
completely impossible.
If I were to write a new language I wouldn't add generics but I guess I am
the exception to the rule but since it can't be done correctly I think
the majority should definetly oppose this.
> Metadata, foreach, static import, enum and generics are just syntactic sugar.
> They each encapsulate popular Java patterns.
I didn't say anything about metadata. I might actually like it since I'm using
XDoclet at the moment and I can't see any problem with it, but I haven't studied
the matter to give an educated opinion.
Sugar makes you fat, makes your teeth rot and doesn't give much in return except
for a taste that doesn't last. This is a great example.
I agree that languages should do as much as possible to help the programmer from
shooting his foot in runtime, but the question is how much help is gained:
1. Generics will help very little and make matters worse to boot (as explained
above).
2. ENUM's encorage people to program as they did in C/C++ (I'm not even going
into the stupid JSR about adding printf() like functionality).
I saw lots of people complaining about Java's performance since they programmed
it like they were in C (using constants etc...) and got none of the advantages
of generic OO code. Adding ENUM's would mean they would use it and NEVER learn
how to program properly, there is no reason to add oil to the fire.
> Foreach, static imports, and enums are extremely easy to learn, add almost
>nothing to the language complexity or ambiguity. This minimal cost needs to be
This "minimal cost" will be much worse:
1. It will "legitimate" modifying the ONLY stable widely used commercial
language that we have. This will harm one of Java's key advantages for
large businesses.
2. It won't be a sweeping change through the API, which will cause AWT/Swing
like inconsistency within it causing confusion to newer programmers.
3. It will make Java code harder to read.
I strongly advocate the approach of James Gosling to resist every change
and redundancy, thats what made Java great to me. Maybe its partially due
to the "trauma" of C++'s ISO process that created this freakish language that
has features to "work around" other features (mutable, virtual inheritance
anyone).
>weighed against the benefits. Static imports get rid of the common incorrect
>pattern of inheritence of constants (i.e. If MyClass needs several constants
If you use global constants then IMO you aren't using Java correcly. There
is no need to add a feature to the language in order to persist a missguided
use case, I myself haven't (neither is has anyone in any team I lead) used
such a thing.
>from Constants, inheriting MyClass from Constants means that MyClass ISA
> Constants.). Foreach and enums reduce reduce the writing of error prone code.
See my earlier post regarding this.
> Is the benefit worth the (small) cost? That's debatable (I think some form of >enum is). My only concern is that with the current implementation of enums is
>how it interacts with EJBs. If enums were simple integers, there would be no
>problems since integers are passed by value, but since enums are classes, there >may be a few class-identity issues.
Your making my case for me, there could be many integration issues we don't
see. This might require working binary servers to be redeployed in order to
support newer client applications...
> Metadata is something that adds little complexity to the language but it's
>impossible to understand without knowing the context of the usage (i.e. the
As I mentioned above, I don't have a personal stance on Metadata.
>same tag can mean many things). To evaluate it, it needs to be compared with
>technology patterns it's trying to replace (e.g. 3 EJB classes for one >implementation class and information in the deployment descriptor) to see if
>there are any real benefits. Anecdotal evidence from XDoclet (it's closest
>cousin) seems to indicate that it may be worth the cost, so the only question
>is whether it's better to incorportate Metadata into the language as a language
>extension, incorporate it in the J2EE library/tools spec, or let 3rd part tools
>like XDoclet handle the feature.
Well, as I said I use XDoclet which I find to be much better than the visual
tools so I am mostly with you on this. In my unofficial opinion I think they
should standarize something similar to XDoclet to avoid language
incompatability.
> Generics, under the current implementation, are fairly restricted, easy to
>understand, and interact well with legacy libraries (e.g. a List<T> can be
> passed to a method that expects a List). They reduce the need for casting,
This is the exact reason why they don't work ;)
> provide more documentation on the usage of collections, reduce the number of
> classes you need, and reduce the error-prone case where you add the wrong
>data-type to a collection. If my experience with C++ is any indication, errors
Why reduce code, you actually write special collections for types?
I just use casts myself which is roughly the same amount of code (both compiled
and as source).
>messages in templated code tend to be more cryptic, although using templated
>code tends to be simpler and easier to explain. Is this feature worth the
>price? I definitely think it's worth it for the standard library collections,
>but whether it's worth it for general purpose programming is debatable. I'm a
>bit concerned, again, how generics interact with EJB code. What happens if you
>say your method passes or returns a generic?
I almost forgot to mention the cryptic nested template error messages, thanks ;)
Regarding the interaction with EJB code... Again a great example regarding
change. -
Well I hope I'm not the only one who thinks these are BAD ideas[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 13 2003 08:12 EDT
- in response to Joshua Y
I think it is deveopers responsibilities to produce cleaner
> codes, not the language features. Seasoned developers first
I had this exact argument a couple of years ago.
However your posting lacked a bit of substance as in real world examples where
generics etc... made a difference.
Feel free to elaborate.
I see mostly academics in favor of generics and other features, most of the
people who actually work on business solutions don't really want change.
So you can claim (justifyable) that this group still uses COBOL, but it works!
Thats very important to us, and by changing something very basic (and forcing
us to change as well) the rug will be pulled from under our feet.
You say that generics aren't complex, while its true they are simpler than
templates they are neither necessary nor helpful:
1. Templates exist in C++ because downcasting is bad. In Java casting isn't
really bad, we don't need RTTI and have dynamic type safety. We have single
inheritance which simplifies everything regarding casting.
2. Generics are complex because they can be nested, imagine the compiler erros.
Anyone who ever used STL to a reasonable extent knows that its far from simple.
3. Generics simplify very simple problems. Joshua himself said that a vast
majority of the collections work with simple types (String, Number's etc...)
Is Collection<String> simpler than a cast? Not really.
I object to adding something that hasn't been proven to solve anything.
If it were a windowing toolkit we would sit a focus group and check whether they
like this feature. Be your own focus group, check for every cast exception or
problem you face and see whether generics will simplify it. I bet it won't.
This is even without rasing the issue that generics arn't backwards compatible
and will cause errors that will take programmers a great deal of time to
understand. I can just imagine the forums flooded with newbie flames and rtfm's. -
enums are the worst[ Go to top ]
- Posted by: aaron evans
- Posted on: April 15 2003 13:26 EDT
- in response to Tero Vaananen
public void foo(MyEnumType myenum);
Class MyEnumType extends EnumType
{
protected void specifyEnumValue(String strValue) {
try {
enumValues.add("strValue");
}
catch (EnumValueAlreadyExistsException e) {
// fail
}
public boolean setValue(String strValue, int intValue) {
if (enumValues.contains(strValue)) {
try {
enumValues.put("strValue", new Integer(intValue);
}
catch (UnableToModifyEnumValueException e) {
// bork
}
//...etc.
Actually, wouldn't it be cool if we used JNDI lookups for enumerated lists, and then we could use remote enums! I'm sure if performance is a problem we could build a cache of frequently used enums, and by the time the hotspot JIT compiler takes care of it, we should be able to perform simple arithmatic, and maybe even string comparisons on our load balanced 16 way Sunfires.
} -
Well I hope I'm not the only one who thinks these are BAD ideas[ Go to top ]
- Posted by: Rashid Jilani
- Posted on: April 11 2003 14:18 EDT
- in response to Shai Almog
I agree with Shai. We can argue all day on fancy language features, but at the end of the day we are making Java very complex just for the sake of competition.
I am amaze no body cares much about the VM reliabilty and scalabilty in today's server centric applications. I like the idea of application domains in .NET, I bilieve Java folks should pay attention to issues like that. -
Typesafe Enums and Generics are very much worth their while[ Go to top ]
- Posted by: Henrik Klagges
- Posted on: April 11 2003 15:14 EDT
- in response to Shai Almog
I wonder why a previous poster has been ranting so much about enums and generics. I find both of them very useful and not ugly at all. Especially generics are a major improvement over "Object"-only containers. The latter force you, if you are a careful programmer, to check each retrieval from the container against a ClassCastException. Not very beautiful, IMHO.
Cheers,
Henrik Klagges
TNGtech -
Typesafe Enums and Generics are very much worth their while[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 11 2003 16:36 EDT
- in response to Henrik Klagges
Henrik, regarding Enums I have neather used them as numeral integers
or "objects pretending to be ENUM's" for the past 5 years and neather
has any developer working under me. The only place I allowed such
constants is in J2ME programming or where an API implementation
(bad API implementation) requires it.
ENUM's are bad since they require switch like hardcoding (even if
you write the code as if statements) which means hardcoding logic
into a single class. Many C++ programms I worked with had central
switch statements that just can't be modified since this will
break something or other. The better approach is to use maps
(I will ellaborate on that to another poster).
Regarding generics my argument is twofold:
1. Generics won't work correctly - since generics MUST be compatible
to current code they have to "pretend" to be regular collection thus
for binary compatability when I use:
class NonGenericBinaryClass {
public void methodThatAddsString(Collection c);
}
Collection<Integer> c;
myMethod(c);
I will get a class cast exception (or worse), this will be hell on
newbies that will spend weeks debugging and on forums.
2. Generics aren't ESSENTIAL, yes it would be nice not to perform
casts. But ask yourself whats so terrible about casting, we still
have type safety (in runtime no less). Even with generics you will
still need to downcast (most of my collections are polymorphic).
Its an additional complexity without any of the benefits simply put
out to satisfy a checkbox feature list in front of C#.
I hope Sun will be strong and keep Java small despite the pressure,
if they feel generics are warranted they should start a new language
that implements them correctly.
Many of the people who disagree with my view of generics do agree that
there is no way to implement them correctly without breaking compatability
and some of these people agree that in that case they shouldn't be used
at all. -
Typesafe Enums and Generics are very much worth their while[ Go to top ]
- Posted by: David Hamilton
- Posted on: April 14 2003 07:57 EDT
- in response to Shai Almog
But ask yourself whats so terrible about casting, we still
have type safety (in runtime no less).
Because, like I said before, the Exception only occurs when you try to cast the Object after getting it out of the Collection, resulting in very had to trace errors (especially on a live or client system without diagnostics on it).
I will get a class cast exception (or worse), this will be hell on
newbies that will spend weeks debugging and on forums.
You will only get a exception if to try to get out types that different from those that are in there... the usage that you outline in your post implies that the code then tries to use the collection as if it contains non-Integer objects... which is poor design, as the code that looks for other objects should be using typed collections.
(most of my collections are polymorphic)
Ahhhh! Here we come to the truth - you don't like generics because you don't actually use typed collections. Personally I have a big problem with heterogeneous collections (asking for trouble IMHO - I like to write robust code!).
OK - if you don't want to use them - don't use them, but don't stop the rest of us from having them.
/david -
Typesafe Enums and Generics are very much worth their while[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 14 2003 11:49 EDT
- in response to David Hamilton
But ask yourself whats so terrible about casting, we still
> have type safety (in runtime no less).
>
> Because, like I said before, the Exception only occurs when you try to cast
>the Object after getting it out of the Collection, resulting in very had
>to trace errors (especially on a live or client system without diagnostics on
>it).
First, I find stack traces rather helpful.
Second, if you get ClassCastException or NullPointerException in deployed
systems then you have a pretty bad problem in your QA process.
> I will get a class cast exception (or worse), this will be hell on
> newbies that will spend weeks debugging and on forums.
>
> You will only get a exception if to try to get out types that different from
>those that are in there... the usage that you outline in your post implies
>that the code then tries to use the collection as if it contains non-Integer
>objects... which is poor design, as the code that looks for other objects
>should be using typed collections.
It won't.
That would require every single API written in Java to be rewriten.
If you have a large code base that makes use of Collection<Integer> and you
will want to make it work with an API that accepts Collection (if only for
backwards compatability) you will have to either cast or copy neither one of
which is bad since the casted object will no longer respect the object contract
and the copyed object will need to be converted back or synchronized.
The ClassCastException a person who will try to cast gets, will surprise many
programmers and confuse them.
> (most of my collections are polymorphic)
>
> Ahhhh! Here we come to the truth - you don't like generics because you don't
>actually use typed collections. Personally I have a big problem with
>heterogeneous collections (asking for trouble IMHO - I like to write robust
>code!).
A. I write robust code too.
B. I don't remember this quote, but I guess I meant to say that most of the
complicated collections on which I spend time are polymorphic. The Number
and String collections are never a problem.
C. I often use Number as a collection cast object to avoid dependency on Integer
Long etc... This IMO if far more robust than Collection<Integer> although that
is subjective.
> OK - if you don't want to use them - don't use them, but don't stop the rest
> of us from having them.
If that were only the case. The reverse is true!
By adding generics they will be forced upon us. Java (and 3rd party) API's will
start passing generic objects and I will have to use the generic syntax in order
to avoid the harmful cast we discussed.
I voted for asserts and I might support Meta-Data since these API's won't burn
the whole Java API and libraries by making them inconsistent and incompatible.
These two changes don't change a basic element of how Java functions and are
not patches over something that was never meant to be. These two features serve
a purpose and actually reduce code, make it more maintainable etc... -
Typesafe Enums and Generics are very much worth their while[ Go to top ]
- Posted by: David Hamilton
- Posted on: April 14 2003 12:33 EDT
- in response to Shai Almog
First, I find stack traces rather helpful.
Me too. Unfortunately the stack trace in this case is for perfectly valid code that is merely trying to handle an incorrectly added object.
Second, if you get ClassCastException or NullPointerException in deployed
systems then you have a pretty bad problem in your QA process.
Wow - can I live in your perfect world too? Hard experience has shown me that users have a tendency to find corner conditions that even the most rigorous testing fails to reveal. (BTW: I do try to avoid potential corner conditions and complexity for that very reaason).
That would require every single API written in Java to be rewriten.
If you have a large code base that makes use of Collection<Integer> and you
will want to make it work with an API that accepts Collection (if only for
backwards compatability) you will have to either cast or copy neither one of
which is bad since the casted object will no longer respect the object contract
and the copyed object will need to be converted back or synchronized.
Ermm, are you referring to trying to pass a types collection to a generic API method, return one back or both?
Passing a typed collection as a parameter should be fine, as long as the library isn't expecting anything other than Object.
Using a library that creates an untyped collection is always going to be an issue (but a very obvious one - you are effectively wanting to downcast, so unless you write an adaptor method to copy the generic data to a typed collection while checking the type of each element, you are going to be on very dodgy ground).
C. I often use Number as a collection cast object to avoid dependency on Integer
Long etc... This IMO if far more robust than Collection<Integer> although that
is subjective.
Really depends whether you want/need to store Integers or Numbers! The important thing is to be consistent - if you're storing Numbers, don't try using them as Integers without checking first!
/david
BTW: Has anyone tried deploying EJB code using Generics in the remote interface to an AppServer yet? What were the results? -
Typesafe Enums and Generics are very much worth their while[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 15 2003 03:29 EDT
- in response to David Hamilton
This might appear twice, the forum crashed and when I tried the back button
it wouldn't let me repost. I don't see the message now that its up so I'll
just repost.
> First, I find stack traces rather helpful.
>
> Me too. Unfortunately the stack trace in this case is for perfectly
>valid code that is merely trying to handle an incorrectly added object.
I disagree, the JavaDoc for the collection types specifically state that any
object is valid. By casting down a generic collection we essentially brake
a contract and lost a much more important element in the process.
This is inconsistent with everything that is Java!
I don't get a lot of ClassCastExceptions and not a single one of them would go
away if generics were added. I bet the same applies to each and every person
in this board.
> Second, if you get ClassCastException or NullPointerException in deployed
> systems then you have a pretty bad problem in your QA process.
>
> Wow - can I live in your perfect world too? Hard experience has shown me that
>users have a tendency to find corner conditions that even the most rigorous
>testing fails to reveal. (BTW: I do try to avoid potential corner conditions
>and complexity for that very reaason).
We have a strong testing policy and use JUnit rather extensively. It cuts down
on development time significantly.
Yes, I write code in a perfect world.
Anyway these type of exceptions (and definetly the ones that are "helped" by
generics) should occur in the most basic test cases. If you do get a class cast
exception from unexpected user interaction it will probably be from a
complicated use case (such as a polymorphic collection?).
> That would require every single API written in Java to be rewriten.
> If you have a large code base that makes use of Collection<Integer> and you
> will want to make it work with an API that accepts Collection (if only for
> backwards compatability) you will have to either cast or copy neither one of
> which is bad since the casted object will no longer respect the object contract
> and the copyed object will need to be converted back or synchronized.
>
> Ermm, are you referring to trying to pass a types collection to a generic API
>method, return one back or both?
Both, the reason to pass a mutable collection to a method is usually in order to
get a result.
> Passing a typed collection as a parameter should be fine, as long as the
>library isn't expecting anything other than Object.
Its expecting a Collection. Say I have a binary library that has a method
addSomethingToCollection(Collection c);
I have a Collection<Integer> that is referenced quite a bit and changing it to
Collection is no longer feasable. I don't have a choice but to cast down.
People will do stuff to avoid this (such as copying the collection) but
no solution is even close to reasonable.
> Using a library that creates an untyped collection is always going to be an
>issue (but a very obvious one - you are effectively wanting to downcast, so
>unless you write an adaptor method to copy the generic data to a typed
>collection while checking the type of each element, you are going to be on very
>dodgy ground).
The type checking is done automatically by the generics implementation. The
problem isn't there! We have a method add(Object) not add(Integer) yet it
no longer accepts Objects. Thats a breach of contract. Interfaces of Objects
are a contract between the developer and the API. Generics will change that
contract and create a world of pain for people trying to figure out why they
don't work. This problem does NOT exist in C++! This is simply a BAD
implementation decision made by the developers of the generics API who knew
generics won't be useful on their own so they made a horrible patch to try
to make them compatible when they really aren't.
> C. I often use Number as a collection cast object to avoid dependency on Integer
> Long etc... This IMO if far more robust than Collection<Integer> although that
> is subjective.
>
> Really depends whether you want/need to store Integers or Numbers! The
>important thing is to be consistent - if you're storing Numbers, don't try
>using them as Integers without checking first!
Why?
The number is the base class and if I need an integer I cast
((Number)obj).intValue();
Sure I try to be as consistent as possible but IMO this is more robust and
just won't fail as long as obj is indeed any type of number.
This allows me to have Currency objects etc... which I need for the presentation
layer.
> BTW: Has anyone tried deploying EJB code using Generics in the remote
>interface to an AppServer yet? What were the results?
Shudder....
Imagine the type of problems we will add since client VM versions are often
different from server VM's. -
Typesafe Enums and Generics are very much worth their while[ Go to top ]
- Posted by: David Hamilton
- Posted on: April 15 2003 05:38 EDT
- in response to Shai Almog
I disagree, the JavaDoc for the collection types specifically state that any
object is valid. By casting down a generic collection we essentially brake
a contract and lost a much more important element in the process.
This is inconsistent with everything that is Java!
Then you and I use collections in a very different way. Almost all my uses of collections involve storing a single class, or a set of classes of a consistent root class or interface.
The important thing is that if the rule with the collection is that if the collection has been deemed to be a Number (say), then I should only ever assume that I'm going to get a Number out. If I assume that I'm going to get a Double, then I am breaking my own contract (and so need to check the type of the object before casting).
By your method you could only ever assume that something is an Object - any further assumption is a breach of contract!!!
The whole point of generic collections is so that the compiler can enforce that contract that the contents must be of a certain type.
> Really depends whether you want/need to store Integers or Numbers! The
>important thing is to be consistent - if you're storing Numbers, don't try
>using them as Integers without checking first!
Why?
The number is the base class and if I need an integer I cast
((Number)obj).intValue();
You're missing the point again. intValue() is a member of Number, so no Integer assumption is required. That's fine.
If however, you wanted to use a method from the Comparable interface (implemented on Integer, not Number), you would have to break the assumption that the contents of the collection were all Numbers. So a test for instanceof Integer would be necessary because you are working outside of the contract that the collection has.
This allows me to have Currency objects etc... which I need for the presentation layer.
So your presentation layer is expecting more information than just Number???
addSomethingToCollection(Collection c);
I have a Collection<Integer> that is referenced quite a bit and changing it to
Collection is no longer feasable. I don't have a choice but to cast down.
People will do stuff to avoid this (such as copying the collection) but
no solution is even close to reasonable.
You're making a good case for generics!! The point is that there is no current way of enforcing that the contents of a collection should be limited to a particular type.
You are say that mixing collection methods that enforce two different contracts (Integer and Object) is bad. YES!!! The point that that at the moment you can do it quite happily without any compiler issues at all - how bad is that? Or even realising that you're doing anything wrong...
Interfaces of Objects are a contract between the developer and the API.
Object contract is the lowest case contract - good developers will use a contract that enforces a higer level contract (EventListener or something) that is actually of use.
If you are saying that the contract is Object, then Object is the most that you can assume about the contents of the collection.
E.g. if a client app fills your collection with Objects he is in perfect compliance of your contract. However, it is highly probably that you won't be able to do any processing on that data, because you really want objects of a different type to Object to be able to do anything useful with it (you are the one that is in breach of contract because you are really expecting something more than Object).
That's why generics are necessary - to allow a more expressive (and useful!) contract between the parties utilising a collection.
> BTW: Has anyone tried deploying EJB code using Generics in the remote
>interface to an AppServer yet? What were the results?
Shudder....
Imagine the type of problems we will add since client VM versions are often
different from server VM's.
Strangely enough, I have my WebServer between my EJBs and my client.
/david -
Typesafe Enums and Generics are very much worth their while[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 15 2003 11:14 EDT
- in response to David Hamilton
I disagree, the JavaDoc for the collection types specifically state that any
> object is valid. By casting down a generic collection we essentially brake
> a contract and lost a much more important element in the process.
> This is inconsistent with everything that is Java!
>
> Then you and I use collections in a very different way. Almost all my uses of
>collections involve storing a single class, or a set of classes of a consistent
>root class or interface.
Thats not what I said!
The container contract accepts an object and it doesn't matter how you
specifically work. If you get a pointer to a collection interface you can add
any object to it... Not any more! That breaks compatability. The WRITTEN
contract (JavaDoc API) between the Java and the user.
Think about it, the first thing you do when an API returns you class X is check
out the JavaDoc for class X. It accepts Object as a parameter for method y()
how lovely. You send a Long object and get a class cast exception...
Is the JavaDoc wrong????
Why no.
The fact that I use a single type in most of my collections as well is not
relevant. If you will look at that code its trivial and adding generics won't
change much. Who gets a class cast exception over a collection of Strings or
Numbers???? The problems occure for that 5% where the collections contain
polymorphic types, there all the generics in the world won't help at all.
I said before, Collection make very little difference for the simple but do
nothing to help the complicated problems.
> The important thing is that if the rule with the collection is that if the
>collection has been deemed to be a Number (say), then I should only ever assume
>that I'm going to get a Number out. If I assume that I'm going to get a
>Double, then I am breaking my own contract (and so need to check the type of
>the object before casting).
Double is a number?
Anyway this isn't an intersting point just an anecdote can we drop it?
> By your method you could only ever assume that something is an Object - any
>further assumption is a breach of contract!!!
By my method unless someone changes the contract explicitly then yes.
Just like in C++ list<string> != list<void *> it doesn't make any sense.
A typed collection should be a new class on its own thus holding a contract
of its own. Code shouldn't be generated explicitly but it should behave like
a different object type.
> The whole point of generic collections is so that the compiler can
>enforce that contract that the contents must be of a certain type.
Thats a legitimate goal, I dissagree with its usefulness and that is a
reasonable debate.
The point is that generics cannot be implemented in the way the JSR
proposed in the current Java VM. Casting them down is just wrong!
and should be deemed an error.
> > Really depends whether you want/need to store Integers or Numbers! The
> >important thing is to be consistent - if you're storing Numbers, don't try
> >using them as Integers without checking first!
>
> Why?
> The number is the base class and if I need an integer I cast
> ((Number)obj).intValue();
>
> You're missing the point again. intValue() is a member of Number, so no
>Integer assumption is required. That's fine.
>
> If however, you wanted to use a method from the Comparable interface
>(implemented on Integer, not Number), you would have to break the assumption
>that the contents of the collection were all Numbers. So a test for instanceof
>Integer would be necessary because you are working outside of the contract that
>the collection has.
Sure I'll have to cast in order to get comparable but why do that?
What contract would I be breaking? I lost you there, I don't use generics
and even if I were casting a Number to an Integer doesn't break anything.
I think I got that, you mean that since I have an Object that I can't cast it
without an instanceof. Aha but the big picture....
I have a wide contract with the collection:
1. A collection is created empty and can be changed only via the object I
created.
2. A collection will maintain all the objects I add and remove all the objects
I remove.
I know I only added Integer numbers thus casting to Intger is OK.
Say I passed the collection to a method, then its contract needs to indicate the
type of objects I get back in the collection. The problem is that people don't
document nor respect these behaviours. However the Java API should always
respect these notions since the API is the most basic contract we all have.
> This allows me to have Currency objects etc... which I need for the
>presentation layer.
>
> So your presentation layer is expecting more information than just Number???
Sometimes, not in this particular application but yes.
> addSomethingToCollection(Collection c);
>
> I have a Collection<Integer> that is referenced quite a bit and changing it to
> Collection is no longer feasable. I don't have a choice but to cast down.
> People will do stuff to avoid this (such as copying the collection) but
> no solution is even close to reasonable.
>
> You're making a good case for generics!! The point is that there is no
>current way of enforcing that the contents of a collection should be limited to
>a particular type.
It still won't. And fixing the internal implementation of a binary library
isn't possible. Now that you know that the library is doing that, how would
you go about fixing this? The vendor won't fix it (soon enough at least) so
my solution will be: "change all the code and remove the generics" this is
assuming the problem is found. It will take them forever to find the problem
and most projects I know will probably just work around the problem.
> You are say that mixing collection methods that enforce two different
>contracts (Integer and Object) is bad. YES!!! The point that that at the
>moment you can do it quite happily without any compiler issues at all - how bad
>is that? Or even realising that you're doing anything wrong...
So you suddenly place a restriction making existing code invalid?
Thats far worse. I'd rather have a problem I know of than a whole set of
new problems.
I'm surprised you don't agree with me that the casting is a bad idea.
I can accept that people want generics (I don't agree but then I don't agree
about many things ;) but I can't imagine that even the biggest generics
advocates want something so broken.
> Interfaces of Objects are a contract between the developer and the API.
>
> Object contract is the lowest case contract - good developers will use a
>contract that enforces a higer level contract (EventListener or something) that
>is actually of use.
That is done by subclassing and you see within the stack trace the specific
element that changed the contract. Furthermore the API documentation will
usually indicate the change of contract: If you have a NumberList then the
API will mention that. You will have to invoke new somewhere.
If you use a library that returns a NumberList then it should indicate that.
> If you are saying that the contract is Object, then Object is the most
>that you can assume about the contents of the collection.
See my explanation above of the full extent of an object oriented contract.
> E.g. if a client app fills your collection with Objects he is in perfect
>compliance of your contract. However, it is highly probably that you won't be
>able to do any processing on that data, because you really want objects of a
>different type to Object to be able to do anything useful with it (you are the
>one that is in breach of contract because you are really expecting something
>more than Object).
Thats just seeking an argument. You know full well what I mean.
There is a contract with a collection but my contract is with the client
library and theirs is within their documentation promissing me the specific
objects I require.
> That's why generics are necessary - to allow a more expressive (and useful!)
>contract between the parties utilising a collection.
Expressiveness is good. But then you end up in perl/C++ or C# all of which are
a total mess IMO. Java places most of its expressiveness in the API which is
where the complexity should be.
> > BTW: Has anyone tried deploying EJB code using Generics in the remote
> >interface to an AppServer yet? What were the results?
>
> Shudder....
> Imagine the type of problems we will add since client VM versions are often
> different from server VM's.
>
> Strangely enough, I have my WebServer between my EJBs and my client.
I ran some projects that had client VM's communicating using serialization
or Corba to the EJB server. This is not uncommon. -
Typesafe Enums and Generics are very much worth their while[ Go to top ]
- Posted by: David Hamilton
- Posted on: April 16 2003 04:42 EDT
- in response to Shai Almog
Hi Shai,
>I'm surprised you don't agree with me that the casting is a bad idea.
Oh, I do think it is a bad idea - if it being done by user (e.g. casting collection 'get' results). If it is checked by, and then added by, the compiler, then I don't see it as a problem.
>That is done by subclassing and you see within the stack trace the specific
> element that changed the contract. Furthermore the API documentation will
> usually indicate the change of contract: If you have a NumberList then the
> API will mention that. You will have to invoke new somewhere.
Yep - that's fine. Perfectly good approach.
One problem: How do you then pass your custom collection to these libraries that you say you need to use?!!! The only ways are
a) To expose the hidden inner list to the library (breaks the contract as the library may add Strings to your NumberList).
b) Implement the general List interface on your NumberList (allows everybody to drive coach and horses through your Number requirement!)
Either way you're stuffed - bottom line is your code and the library are trying to do different things with the data. Like I said (ages ago), the problem is with conflicting contracts, not generics.
Having said that, I do think that there you have raised an interesting point that some work might need to be done on the whole reflection side of generics. Anyway, I've got a clustering config to set-up, and I think we're about done this to death. Cya.
/david -
Typesafe Enums and Generics are very much worth their while[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 16 2003 06:24 EDT
- in response to David Hamilton
Hi Shai,
>
> >I'm surprised you don't agree with me that the casting is a bad idea.
>
> Oh, I do think it is a bad idea - if it being done by user (e.g. casting
>collection 'get' results). If it is checked by, and then added by, the
>compiler, then I don't see it as a problem.
I was refering to casting a generic collection to a regular collection.
Generic folk are usually very much against casting (which usually doesn't cause
much damage in Java) this is a case where damage is REALLY caused by a cast
operation.
> >That is done by subclassing and you see within the stack trace the specific
> > element that changed the contract. Furthermore the API documentation will
> > usually indicate the change of contract: If you have a NumberList then the
> > API will mention that. You will have to invoke new somewhere.
>
> Yep - that's fine. Perfectly good approach.
>
> One problem: How do you then pass your custom collection to these libraries
>that you say you need to use?!!! The only ways are
I never said that the NumberList hid the Collection within it. IMO a NumberList
can implement the collection interface and fail in a similar way to generics
(since it breaks the contract as well).
However:
1. This is something I know about since I have to create the NumberList in order
to do this.
2. I will see the NumberList class in the stack trace and know who to blame.
3. This contract change, affects me and my code ALONE, this is not a wide
sweeping change. No one will be forced to use this list unless they use my
library.
> Either way you're stuffed - bottom line is your code and the library are
>trying to do different things with the data. Like I said (ages ago), the
>problem is with conflicting contracts, not generics.
As I said, HUGE difference.
Theres bad code in Libraries and then there is the language that should be
squeeky clean.
> Having said that, I do think that there you have raised an interesting point
>that some work might need to be done on the whole reflection side of generics.
>Anyway, I've got a clustering config to set-up, and I think we're about done
>this to death. Cya.
I have to agree, I have a delivery deadline as well and I think you see my point
at least in general. I hope you do agree with me eventually that generics can't
be just a small compiler change but if at all be a more serious robust change.
Hopefully when generics start failing for people google will prove I did
everything to stop it from happening ;) -
Prefer not to work for Shai[ Go to top ]
- Posted by: Robert White
- Posted on: April 16 2003 18:55 EDT
- in response to Shai Almog
Given the non-provisional way that Shai states his opinions, I would prefer not to work for him. And given that I disagree with his pontification regarding enums, I rather doubt I'd be given a chance. Suffice to say, however, that if he were working for me (or "under me" as he so patronizingly put it), I would not fire him for his obtuseness, because I believe that even the most closed-minded person can be reformed.
Enums have the advantage over simple integers that the compiler catches certain errors that most of us, other than Shai, commit from time to time (and seeing the misspellings in his post, I suspect that even Shai makes a typo now and then).
As well, the "objects pretending to be ENUMs" are a concise idiom for constructing a set of objects as if building a table.
public class EnumLike {
private EnumLike( int i1, String s2, ..., Border oN ){ ... }
static public EnumLike Wash( 0, "Washington", ..., new EmptyBorder() );
static public EnumLike Adams( 13, "Adams", ..., new BeveledBorder() );
...
static public EnumLike Bush( -10, "Bush", ..., new EtcBorder() );
}
This gives us the ability to refer to well-known static object references (e.g. EnumLike.Wash, EnumLike.Adams, etc.) and all of the particulars of a particular aspect are retrievable from any of those objects. The alternative is to put these objects in a Map and use a different constant (probably a string, to retrieve the object of interest).
Map NoEnums;
NoEnums.put( "Washington", new NoEnum( 0, ..., new EmptyBorder() ) );
NoEnums.put( "Adams", new NoEnum( 13, ..., new BeveledBorder() ) );
NoEnums.get( "Washington" );
I just don't see what's wrong with the "EnumLike" idiom and I admire its concision. -
Prefer not to work for Shai (not much of a chance)[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 17 2003 04:51 EDT
- in response to Robert White
Given the non-provisional way that Shai states his opinions, I would prefer not to work for him.
>And given that I disagree with his pontification regarding enums, I rather doubt I'd be given a
>chance. Suffice to say, however, that if he were working for me (or "under me" as he so
>patronizingly put it), I would not fire him for his obtuseness, because I believe that even the most
>closed-minded person can be reformed.
Somehow we will manage without you.
Programming is teamwork. If a team doesn't share a unified vision (usually in the form of a
strong leader) a team will fail. Every single project I lead finished ahead of schedule under budget
and with high quality. How many people here can say that? I'm a tough person to work for, but I
do have the time to explain everything (as indication check the number of posts I bothered to
place here), but if a person won't agree with me or worse if he tries to sneak in code that is
not quality code... That person will be fired.
Regarding the use of the term "under me", some of the people I manage are not employees of
the company since we do outsourcing work and so I am not their boss but I do manage them.
Please feal free to suggest a different term to indicate that I am not the boss yet have
responsibility for their work (under my supervision?).
It seems to me that you have a personal problem with my approach, frankly I couldn't care less.
I have people standing in line to work for me in projects and my reputation is tough but
fair, if you play by my rules.
> Enums have the advantage over simple integers that the compiler catches certain errors that
>most of us, other than Shai, commit from time to time (and seeing the misspellings in his post, I
>suspect that even Shai makes a typo now and then).
1. English is not my native language and I never lived in an English speaking country. I think I'm
doing rather well with the spelling mistakes and grammer all things considered.
2. I never said I don't have bugs/typos or coding mistakes.
I did say that ENUM's are redundant and that using integers as ENUM's is just as bad!!!
If you would have bothered to read my posts I never said anywhere or gave any example
that would contain a hardcoded integer number, no room for typos of the type that ENUM's
can fix.
That if why you probably will never get a chance of working here, opening your flame thrower
rather than trying to understand a different view. Unlike you while my opinions are firm and
I apply them religiously, I didn't aim to insult anyone personally but tried to politly explain.
> As well, the "objects pretending to be ENUMs" are a concise idiom for constructing a set of
>objects as if building a table.
I never would use anything like this example again you didn't bother to read my
other posts or understand.
check out http://www.theserverside.com/home/thread.jsp?thread_id=18791&article_count=107#79588
ENUM's are a solution for a problem that shouldn't exist in the first place, the application should
handle these problems with polymorphisem and storage solutions.
Give me a single "real" problem that requires ENUM's and cannot be solved in a better
way (where better is defined in terms of generic, dynamic, performance, code size).
There isn't such a problem, except for manufactured problems where ENUM's already exist. -
I remain unconvinced of the danger of Enumerated types[ Go to top ]
- Posted by: Robert White
- Posted on: April 18 2003 00:42 EDT
- in response to Shai Almog
Somehow we will manage without you.
Of course you will, but I think it presumptuous to aver that you will manage better without the ideas of those who disagree with you from time to time? And, by the way, the janitor in our office manages without my help, too.
> Programming is teamwork. If a team doesn't share a
> unified vision (usually in the form of a strong leader)
> a team will fail.
A team needs both a strong and a wise leader and a wise person knows not to presume that he always knows best.
> Every single project I lead finished ahead of schedule
> under budget and with high quality. How many people here
> can say that?
Then you obviously haven't worked for some of the jerks I've worked for. There is no reasonable schedule that could not be made impossible by truncating the time required to complete it. When one works for people with no understanding of software development, one learns to be dismissive of the arbitrary deadlines they sometimes create. In my second job (back in 1981) the salespeople would promise programs that no one had ever even heard of, much less spec'd out, and we were told to complete the job in X months (and this was Z80 assembly!). It can be done, but it's usually not pretty.
My point is, if you have always come in under budget, it is due in part to your brilliance (I mean that sincerely) and in part because you were given the resources. And sometimes people fail to make their deadlines (or make them only by working too much overtime) because the schedule/budget was unreasonable. And for that reason, your boast about your past successes paints only part of the picture. It does not prove your point that your strong leadership (or what I characterized as closed-mindedness) accounts for your success. You may be right, but you have failed to prove that you are right.
And, of course, there is no need to do so here. I will stipulate that you sound very successful. But this does not, nor will it ever, validate your approach to SD mgt. I've worked for people like you (dare I say, dictatorial) and I've worked for managers who let big projects spin out of control. I have come to prefer working for someone who balances the need to control with the need to delegate responsibility and accept the diverse talents of others.
> but if a person won't agree with me or worse
> if he tries to sneak in code that is
> not quality code... That person will be fired.
Well, I doubt anyone would suggest that insubordination be tolerated, however, I will argue that even a brilliant person can be wrong from time to time. In fact, I think you are wrong regarding enums. And I would hate to have you overruling me on this because of your own sense of what's best, because:
a) it's not that critical -- divergence on this issue would, at least sometimes, not cause the kind of unmanageability you suggest.
b) intelligent people should be allow to disagree -- to forbid dissent is invalidating to the intelligence and experience of one's co-workers.
> Regarding the use of the term "under me"...
Since English is not your native language, you are perhaps less sensitive to the connotations of the particular phrase you chose. There's nothing wrong with the term "under" in this case, but it does tend to amplify the notion that you are not only supervising your employees, but are above them, that is, superior to them. My boss is not my better. I am his subordinate, but not his subject.
> It seems to me that you have a personal problem
> with my approach, frankly I couldn't care less.
Well, if I worked for you it would be my personal problem. Since this is merely an online discussion, it doesn't represent a problem for me at all. The only problem here is that of trying to clearly express our views (and that doesn't seem to be much of a problem for either of us). And, yes, if I worked for you I would probably hate it. But you would never know, because part of being a good employee is hiding one's contempt for a person who has control over one's life and little regard for one's livelihood.
> I have people standing in line to work for me in projects
> and my reputation is tough but fair, if you play by my rules.
And that proves, what exactly? Your point about firing people -- your point -- was intended to add weight to your opinion about the technical issues of this thread. It does not do that. And that is my point.
Besides, where do you work? Some poor third world country? People do not choose to work for people like you when they have a choice.
It is irrelevant that I have no problem finding a job, nor how long I have worked, nor the various satisfied employers who would recommend me. It adds no weight to my considered opinion that enums are not a bad thing in every case. I don't try to bully people into agreeing with me.
And I think that truly strong leaders realize that.
> 1. English is not my native language and
> I never lived in an English speaking country.
> I think I'm doing rather well with the spelling
> mistakes and grammer all things considered.
Ah, so quick to forgive his own foible and even quicker to condemn others for the mistake of disagreeing with him. I have worked with many non-native English speakers and it truly is not an issue (ask my Ukrainian wife). Hypocrisy bothers me. I suppose that's another of my personal problems: abhorrence of hypocrisy.
> 2. I never said I don't have bugs/typos or coding mistakes.
No, and I do understand your main point that it's a bad idea, as a rule, to substitute an enumerated type for a class type. For example, if we had a program that referenced 4 identical printers, that differed only in their network name, it would be reasonable to put these names in a String array. It would be folly to create separate classes for these printers and to require that, with each new printer, we must create a new class. However, if one printer were for barcodes, another a character-only line printer, still another a laser printer and the fourth a color printer, it would be folly to create a single Printer class containing an enumerated type to distinguish them.
// Bad idea
static final int PR_BARCODE = 0;
static final int PR_LINE = 1;
static final int PR_BWLASER = 2;
static final int PR_COLOR = 3;
class Printer {
int type;
void print()
{
switch( type )
{
...
}
}
}
Changing this int to an enum is only slightly better -- BUT it is better. Still, I take your point that subclassing would help here. We would prefer the Printer class contain an abstract print() method. In such a case, the mechanism of virtual functions eliminates the need for the switch statement. Each subclass implements its own version of the print() method. Common functionality ends up in the superclass. Differentiation resides in the subclasses.
However, if the ONLY method in the subclass was
String getName(){ return "Bob's Printer"; }
I'd have a hard time justifying the expense of loading the class and using the virtual function mechanism.
String[] sPrinterNames = { "Bob's Printer", "Shai's Printer", ... };
seems more appropriate. Even a switch statement seems better to me:
switch( type )
{
case BOB: return "Bob's Printer";
etc.
Experience teaches us when to subclass and when to tabularize. I reject the doctrine that forbids tables, but then I'm not very religious to begin with.
Going further, we are not always in control of every interface we design. In fact, there are many situations where one must interface with external libraries which demand that we use magic integer values. Any Windows programmer is familiar with this situation. Surely, we can accept enumerated types to substitute for these constants. Color constants are another case. Isn't Color.RED clearer and more type-safe than 0xff0000? Would you not concede that enums are an improvement over final ints when dealing with native and legacy software, as well as with firmware?
At its core, what we're debating here is where type information shall be located. Must it always be located in the class hierarchy? Is there no other instance where we would choose to manage our types manually?
I would state emphatically yes, there are greater than zero times where this is appropriate. You seem to be stating, just as emphatically, that there is never (other than the unavoidable native/legacy/firmware instances) EVER any justification for managing types manually. Sometimes I admire certainty, but this is not one of those times.
> That if why you probably will never get a chance
> of working here, opening your flame thrower
> rather than trying to understand a different view.
Now if this isn't the pot calling the kettle black. Which of us is really the more rigid in his thinking? Answer honestly now. You are the one suggesting that there is NO instance in which enums are useful. If you really believe that you can eliminate the need to interface with hard-coded integer values, then you must have next to no real world experience (and I don't believe that).
> Unlike you while my opinions are firm and I apply
> them religiously, I didn't aim to insult anyone
> personally but tried to polit[e]ly explain.
Is it insulting to suggest that I would prefer not to work with you? Did I not state my belief that even people with a closed-mind can be reformed? Perhaps it was over the top to characterize as obtuse your firm and absolute stance against something that many others value. It is rather a harsh word and, since we are not known to one another, it was impolite. But not inaccurate.
Obtuse can mean "insensitive", and you seem that to me. It can also mean slow to perceive, and here again, your vituperative attacks upon a technique that others have employed profitably seemed to demonstrate a slowness to realize the value of the technique.
I did not find your comment that you would fire a person for using enums to be very polite. Have you ever been out of work? Can you imagine the distress that would bring to such a person? And you would do this to somebody over a disagreement over a miniscule element of design? What if someone were to read your otherwise erudite comments and take you seriously? "Show of hands, people: Who would choose to work under these circumstances?".
> ENUM's are a solution for a problem that shouldn't exist in the first place
a) perhaps these problems shouldn't exist, but they do
b) such solutions are often more concise and efficient than the alternative.
> the application should handle these problems
> with polymorphism and storage solutions.
"May" handle these problems, not "should", not "must". It is impolite to state things unprovisionally. One convinces by dint of reason, not by demand. Better to coax one's readers into agreeing with you than to insist that they agree.
Let's examine polymorphism (although, I think inheritence provides you with a stronger argument). Are these the alternatives?
class foo {
// Alternative 1
// let A,B & C be legal enumerated values of the type variable.
void method( enum type )
{
switch( type )
{
case A: methodA(); break;
case B: methodB(); break;
case C: methodC(); break;
}
}
// Alternative 2
method( ClassA a ){ }
method( ClassB b ){ }
method( ClassC c ){ }
}
It's impossible to state which of these solutions is better. One must know whether or not there are other data related to the types (data which are both relevant and available at the time the method is evoked). If I happen to have 3 types of fully constructed objects, then yes, polymorphism is nice and ever so slightly more efficient than the switch statement (because the method address is indexed -- a quick lookup and jump -- rather than a series of comparisons and branches).
But what if the type corresponds to a user's choice? Imagine a radio button in a dialog in which a customer selects which method he prefers to be contacted: email, phone, fax? Somewhere I will store each of these pieces of data, but not when I ask him to choose. And someday we may use this fact to generate an email, phone call or fax, but not today -- not when the user clicks "Okay" on the dialog box. Indeed, the GUI choice we solicit may not need to persist, but may have a lifetime shorter than the current "session". Must I store this choice as a class? Is there no reason to store this "type" as a simple integer (or, better yet, a typesafe enum!)?
> Give me a single "real" problem that requires
> ENUM's and cannot be solved in a better
> way (where better is defined in terms of
> generic, dynamic, performance, code size).
Well, you give it yourself. Your Airplane class, for example, would be silly if the only distinguishing characteristic between airplanes was its type (or, as in my Printer example, its name).
My rule of thumb is to attempt to collect the distinguishing aspects of varying "types of instances" (I'm purposely avoiding the use of the term class) until a class is required. A class is required when these instances need to contain not just data that can be stored in a table, but behavior (code) as well (and even then, when the behavior is trivial compared to the larger body of common behavior, or when not all instances require distinct behavior, I'm tempted to (gulp) keep a type variable).
As for performance, type variables are usually going to be more efficient. Consider how efficient it is to define constant integers and make occasional comparisons to an integer value generated by an event external to our class (or database lookup or whatever). This compares favorably to the cost of loading just one other class (with the security checks etc). It's a negligible difference, but there had better be a reason for loading that class and perhaps constructing an object of its type beyond the elimination of a switch statement.
Let's consider the 2nd example you give in your response to Valentin...
class MyObject {
public void myFunction(Enum param) {
switch(param) {
// this is a huge bottleneck in the project
// since this might grow very large causing
// both performance overhead and the need
// for multiple developers to work on a single
// large method
}
}
}
The key word here is "might". Such a switch statement might grow very large, but in many instances it will be known with near absolute certainty to remain small. Must I abandon the obvious and simple switch statement to satisfy a doctrinaire design technique? I must if I want to work for you, apparently.
> A better way is to split this type of functionality to
> multiple methods and classes.
You see, this is the kind of absolute, non-provisional statement that gets my goat. Sometimes it is better to invent classes and invoke virtual methods. Sometimes. Not always.
Okay, now for your 3rd example...
>>> 3. You need to perform code according to a numeric value
and have a single entry point.
public class LoadFile {
private void loadObjectFromXMLData(int value) {
switch(value) {
case FIRST_TYPE:
// perform code
}
}
}
should be written as a map lookup
public class LoadFile {
private void loadObjectFromXMLData(int value) {
((Runnable)actionMap.get(new Integer(value))).run();
}
}
<
Now this one takes the cake. Do yourself a favor and next time you're debugging code (I assume you still have to do that, sometimes managers move beyond this and lose touch with the vagaries of the tasks assigned to people "under" them). Do yourself a favor and step into the get() routine of, say, HashMap. Watch as it computes the hash value of the Integer value (and don't forget that the Integer object references the int value indirectly and generates a reference which has to be managed for later garbage collection). Watch as it runs through the for loop looking for a match. This will not, under ANY circumstances result in significant performance boost -- and for sufficiently small sets of enumerated values, the switch statement will win the race hands down (and int's may be stored on the stack and are never separately garbage collected).
> While this is just as verbose as a switch statement, it
> has the advantage of being dynamically extensible, and
> easier to extend as a part of an API.
The static solution has the advantage of being determinate and anybody who debugs on a regular basis can appreciate the advantage of determinacy for debugging. One can set a breakpoint on a case, one cannot do so on a get() -- well, you can, but then you get to enjoy the trip through the lookup process on your way to the execution of the run() method.
But I suppose your suggesting that each case is replaced by a unique class whose sole purpose is to encapsulate the behavior of the case block. I guess I find this approach more verbose. Even though I have used this wherever necessary, I would hardly suggest that it was the only acceptable approach! And to do so for the Runnable example you give (admittedly, contrived for its simplicity, so it can be forgiven for its simplicity) is preposterous.
Moreover, the switch statement is encapsulated, the actionMap solution could potentially be spread throughout the source code (potentially, I didn't say it would be done intentionally). In fact, one could implement the Runnable interface in any library, including those for which you have no source code and for which you haven't a clue as to its side effects. Obviously, you would attempt to eliminate this problem by restricting access to the actionMap (you would restrict access to the actionMap, wouldn't you?).
Please, I beg you. Abandon your miscreant creed. You will not go to hell for using a switch statement. I won't go so far as to suggest that example 3 is lunacy, but it is certainly bizarre in the face of any simple set of enumerated values -- which most are! Each subsequent invocation of this method could cause a new class to be loaded -- how is that better than a handful of branches?
So, let me say this politely, you have a long way to go before you have PROVEN your point and I feel sorry for anybody who actually gets fired for disagreeing with you. In fact, to recap my original point, I feel sorry for anybody who has to work under that Draconian threat. -
I remain unconvinced of the danger of Enumerated types (part 1)[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 18 2003 10:00 EDT
- in response to Robert White
Somehow we will manage without you.
> Of course you will, but I think it presumptuous to aver that you will manage
>better without the ideas of those who disagree with you from time to time?
I specifically said I am always open to listen, otherwise we wouldn't have this
conversation would we? I read every single word you have written, yet people
need to convince me with facts not religions or habits!
That being said, once a decision is made then it should either be completely
reveresed or completely followed by everyone in the team. If we try to play
a different game and everyone has a methodology of its own the team fragments.
Here we play to win, and we do, the only way to do this is together. If a team
member disagrees with me and remains unconvinced then he would probably prefer
working in another team anyway rather than working for me where he will have to
align himself to the rest of the team.
While I can't force everyone to code exactly like me, I try to bring them as
close as possible to this goal. This produces huge code bases, that look as
if they were written by a single person, heavily documented and consistent in
their basic concepts.
The code is immediately obvious as if I myself wrote it, since it is so
consistent.
>And, by the way, the janitor in our office manages without my help, too.
Again, with degrading remarks. When you have nothing clever to say you
choose to resort to puns supposedly on my expense rather than an actual
argument.
> > Programming is teamwork. If a team doesn't share a
> > unified vision (usually in the form of a strong leader)
> > a team will fail.
> A team needs both a strong and a wise leader and a wise person knows not to
>presume that he always knows best.
I never said I know best. I am more experienced in the field than most.
A fresh mind provides intriguing questions and we should always question what
we know as facts. That is why I sit down with every new member and convince
them. They try to convince me, so far I remain unconvinced while every single
member of any team I lead (quite a few people) is convinced!
Anyway again with the remarks supposed to attack me personally, would I even
bother writing back for every comment you made if I was as you try to present
me? I'd love to flame you back right now, since you arrogantly assume about
a person you have no way of knowing? How closed minded is that?
> > Every single project I lead finished ahead of schedule
> > under budget and with high quality. How many people here
> > can say that?
> Then you obviously haven't worked for some of the jerks I've worked for.
>There is no reasonable schedule that could not be made impossible by truncating
>the time required to complete it. When one works for people with no
>understanding of software development, one learns to be dismissive of the
>arbitrary deadlines they sometimes create. In my second job (back in 1981) the
>salespeople would promise programs that no one had ever even heard of, much
>less spec'd out, and we were told to complete the job in X months (and this was
>Z80 assembly!). It can be done, but it's usually not pretty.
I never made people work all night or extra hours and projects run smoothly. I
won't accept a project we can't complete in time. To do this I need total
controll, both over the team so they put their resources in the right place
and over the customer contract.
Thats another perk of working for my team, the job gets done and while the
stress is heavy at first to learn a new way of thinking, once that is done
everything is easy sailing.
The problem with your managers was that they weren't software developers, I am
so when I sit with a customer I know every person on my team and his exact
ability. I sit down and code with every person here!
> My point is, if you have always come in under budget, it is due in part to
>your brilliance (I mean that sincerely) and in part because you were given the
>resources. And sometimes people fail to make their deadlines (or make them
>only by working too much overtime) because the schedule/budget was
>unreasonable. And for that reason, your boast about your past successes paints
>only part of the picture. It does not prove your point that your strong
>leadership (or what I characterized as closed-mindedness) accounts for your
>success. You may be right, but you have failed to prove that you are right.
Thanks, but no it doesn't prove the point. Its a part of a big picture.
Since I own the company I work for I am the manager and team lead for
the larger projects. You could say that my management skills (as in assigning resources) outway my team leader skills, but I disagree. They are a single
package.
I worked for many team leaders before, those that had the hands on approach
where they knew every line of code always ran the project better. Having a
single team work as that a team, is something I never saw until I became a
team leader myself. This is just not done in other companies because the
managers aren't all technical or simply don't have time to code.
Since we deliver source code to some of our customers our release is much more
complicated than most projects, we need to make sure that the code we deliver
is up to the strict standards and our reputation. That makes our requirement
for strict management and consistency even more essential.
> And, of course, there is no need to do so here. I will stipulate that you
>sound very successful. But this does not, nor will it ever, validate your
>approach to SD mgt. I've worked for people like you (dare I say, dictatorial)
>and I've worked for managers who let big projects spin out of control. I have
>come to prefer working for someone who balances the need to control with the
>need to delegate responsibility and accept the diverse talents of others.
I can live with that, I recently fired a person who had a great deal of
experience because we both kept fighting over everything. It started out as
discussions turned to arguments and eventually he did what he wanted regardless.
The way I see it, is that he had already formed ideas of his own and was
unwilling to merge them with mine. Frankly I think people I trained who finished
colege 1 year ago are better programmers than him because they aren't stuck
like him in the way he learned 10 years ago.
I think every project needs one direction, since you said these managers weren't
technical then you naturally needed to take the technical lead but needed a
manager strong enough to take the management lead (which you didn't want).
A project doesn't need two heads, that only leads to trouble. A project needs
consistency, maybe I'm too rough for some of the employees but they learn
more here than they ever did in college. I bring them into my mind and teach
them the way I think and solve design problems.
> > but if a person won't agree with me or worse
> > if he tries to sneak in code that is
> > not quality code... That person will be fired.
> Well, I doubt anyone would suggest that insubordination be tolerated, however,
>I will argue that even a brilliant person can be wrong from time to time. In
>fact, I think you are wrong regarding enums. And I would hate to have you
>overruling me on this because of your own sense of what's best, because:
> a) it's not that critical -- divergence on this issue would, at least
>sometimes, not cause the kind of unmanageability you suggest.
> b) intelligent people should be allow to disagree -- to forbid dissent is
>invalidating to the intelligence and experience of one's co-workers.
I allow disagreement when it comes to conference room issues, but when we sit
down to code there is no room for that.
Feal free to convince me of the need for ENUM's as practically every developer
I ever hired tried to. If you make a single factual claim I can't rebuttle then
I will allow it to my team members. This has been my policy all along, debate
decide and do.
I never overrule any employee who is interested in factual debate and reasoning.
I don't ever "force" someone to use my methodology, but if he doesn't then he
isn't a part of a team. I do have a problem with "briliant" people, they can
create amazing things, but then the steps needed to turn that messy code in
to an actuall working product far outweight the benefit. There was a guy I know
(briliant) who wrote an amazing module we needed (I wasn't a team leader then),
no indentation/comments whatsoever. Since it didn't work correctly fixing it cost so much... I doubt it was worth it (yes I know there are tools to indent).
I had a problem not so much with briliant people, but with primadonnas who
know they are briliant and are unwilling to become a part of a team. IMO they
should be made managers on their own, since they obviously can't work under
any strong manager.
> > It seems to me that you have a personal problem
> > with my approach, frankly I couldn't care less.
> Well, if I worked for you it would be my personal problem. Since this is
>merely an online discussion, it doesn't represent a problem for me at all. The
>only problem here is that of trying to clearly express our views (and that
>doesn't seem to be much of a problem for either of us). And, yes, if I worked
>for you I would probably hate it. But you would never know, because part of
>being a good employee is hiding one's contempt for a person who has control
>over one's life and little regard for one's livelihood.
While I don't need employees to like me, and while they are always friendly
I know I will never really be their friend. Thats true for every boss.
I doubt it if I will miss contempt, that employee I fired had it, I may not be
sensitive but even a guy like myself can catch on to that.
While firing people used to be hard, it became rather easy the moment I
understood a few things:
1. An employee who causes problems by either not going with regulations and
refusing to discuss the issue to the full extent (or incapable of doing so)
will cause the company damage in a project thus hurting our reputation.
2. By harming the reputation our business will suffer.
3. Business suffers I will have to fire people who don't deserve it and who
did a great job.
The way I see it, every person I fire is a problem, if I have any regret its
not firing problematic people sooner. So you can say I have little regard for
a persons livelyhood but IMO the opposit is true, I choose to be loyal to the
livelyhood of the people who actually want to work for the team! I don't fire
people to spite or to line my bank account with more cash.
However I guess what your saying is that people will be afraid of firing if
they disagree. Well clearly you never spoke to either my employees or myself.
They always question me because they know they will get an ellabrorate answer
as to why I want something in a particulart way. They often argue because they
don't understand why I made a decision. They sometimes win these arguments!
Sure, a newer employee might be intimidated to bring something up to me, so they
will usually talk with their fellow employees who will either convince him or
be convinced themselves, thus the more experienced employee who is more
comfurtable approaching me will be the one to argue with me.
Our office doesn't have doors or cubicals, everyone sits together in roughly
similar settings (including myself). IMO all team members are equal in their
treatment and sometimes the newest member can provide fresh insite into the
problems at hand.
> > I have people standing in line to work for me in projects
> > and my reputation is tough but fair, if you play by my rules.
> And that proves, what exactly? Your point about firing people -- your point
>-- was intended to add weight to your opinion about the technical issues of
>this thread. It does not do that. And that is my point.
>
> Besides, where do you work? Some poor third world country? People do not
>choose to work for people like you when they have a choice.
HAHAHAHAHA.
Are you an American ;)
You think everywhere else is third world ;)
Yes we live in a desert thinking about blue jeans....
This single paragraph has made everything worth while I almost wet myself.
I live in Tel Aviv, and trust me, its nothing like any news report you ever
saw or how you imagine it. Israel is about as western as the rest of Europe
and up to the recession people made MORE money here than in the US!!!
When I started off the shortage of employees was so great I had to hire people
out of the second year of colege (who barely had 2 days a week for work).
You need to get out of your shell a little bit and see the world, while yes
there are poor regions everywhere in the world (even in the US) most of the
world (even the third world of which we are not a part) has plenty of jobs
for educated people.
I remember US companies coming here looking to move work offshore to save costs
and being surprised that the costs didn't go down...
> It is irrelevant that I have no problem finding a job, nor how long I have
>worked, nor the various satisfied employers who would recommend me. It adds no
>weight to my considered opinion that enums are not a bad thing in every case.
>I don't try to bully people into agreeing with me.
I am a bully, intelectually. I am willing to pit my knowledge against anyone.
You can say that I have the power to fire people which makes me a bully, but
so does every team leader and manager. I never onced used (and never will) use
it for someone who is willing to have a civil debate and reach a conclusion.
A person can feel free to present a single factual example to convince me.
> > 1. English is not my native language and
> > I never lived in an English speaking country.
> > I think I'm doing rather well with the spelling
> > mistakes and grammer all things considered.
> Ah, so quick to forgive his own foible and even quicker to condemn others for
>the mistake of disagreeing with him. I have worked with many non-native
>English speakers and it truly is not an issue (ask my Ukrainian wife).
>Hypocrisy bothers me. I suppose that's another of my personal problems:
>abhorrence of hypocrisy.
Where was I a hypocrit?
Again with the personal attacks?
Anyway, I doubt your with has better spelling than I when typing in this speed?
If so then cudos to her. -
I remain unconvinced of the danger of Enumerated types (part 2)[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 18 2003 10:01 EDT
- in response to Robert White
[Snipped code we agree is bad]
> Changing this int to an enum is only slightly better -- BUT it is better.
>Still, I take your point that subclassing would help here. We would prefer the
>Printer class contain an abstract print() method. In such a case, the
>mechanism of virtual functions eliminates the need for the switch statement.
>Each subclass implements its own version of the print() method. Common
>functionality ends up in the superclass. Differentiation resides in the
>subclasses.
>
> However, if the ONLY method in the subclass was
> String getName(){ return "Bob's Printer"; }
> I'd have a hard time justifying the expense of loading the class and using the
>virtual function mechanism.
> String[] sPrinterNames = { "Bob's Printer", "Shai's Printer", ... };
> seems more appropriate. Even a switch statement seems better to me:
> switch( type )
> {
> case BOB: return "Bob's Printer";
> etc.
Ok, if we were talking C++ then you might have had a minor point.
Talking Java:
1. If indeed it is only a name then I would simply create a printer with a
string for name (but I realize this is not where you were going).
2. Subclassing has a minor loading cost in Java, however this cost occurs
only once and the gained performance is huge. Both Sun and IBM JIT's perform
virtual method inlining which COMPLETELY removes the cost of a virtual method
call making it as fast as a C++ inline method.
3. Subclassing can be made by an annonimous class which won't cost in code
more than a switch statement.
Both of the approaches I suggested will be faster and require less code than
ENUM's.
> Experience teaches us when to subclass and when to tabularize. I reject the
>doctrine that forbids tables, but then I'm not very religious to begin with.
I use table, in the database where they belong.
Yes experience teaches us everything, but there is never a case to using ENUM's.
Not in an object oriented JITed language. You will only hinder the performance
of the JIT.
> Going further, we are not always in control of every interface we design. In
>fact, there are many situations where one must interface with external
>libraries which demand that we use magic integer values. Any Windows
>programmer is familiar with this situation. Surely, we can accept enumerated
>types to substitute for these constants. Color constants are another case.
>Isn't Color.RED clearer and more type-safe than 0xff0000? Would you not
>concede that enums are an improvement over final ints when dealing with native
>and legacy software, as well as with firmware?
To some degree yes, but the JNI interface can present an OO view and frankly
I can't think of a single use I made of Color.ENUM rather I always extracted
the color value from a database or a properties file. A real application does
that. ENUM's won't be able to replace Color.RED since the RED int is an actual
RGB value and an ENUM would have to map to that value.
> At its core, what we're debating here is where type information shall be
>located. Must it always be located in the class hierarchy? Is there no other
>instance where we would choose to manage our types manually?
No thats not we are debating. We are debating whether type information is needed
for a patch that is no longer necessary in a modern OO language.
> I would state emphatically yes, there are greater than zero times where this
>is appropriate. You seem to be stating, just as emphatically, that there is
>never (other than the unavoidable native/legacy/firmware instances) EVER any
>justification for managing types manually. Sometimes I admire certainty, but
>this is not one of those times.
Certainty has nothing to do with it. Grep over the code I and my teams wrote
in the past 5 years have a lot to do with it. No public static final variables
to be seen anywhere.
> > That if why you probably will never get a chance
> > of working here, opening your flame thrower
> > rather than trying to understand a different view.
> Now if this isn't the pot calling the kettle black. Which of us is really the
>more rigid in his thinking? Answer honestly now. You are the one suggesting
>that there is NO instance in which enums are useful. If you really believe
>that you can eliminate the need to interface with hard-coded integer values,
>then you must have next to no real world experience (and I don't believe that).
I have a strong rigid opinion which I am willing to base on facts which i
have already put. You so far gave one bad example which I answered, your turn.
> > Unlike you while my opinions are firm and I apply
> > them religiously, I didn't aim to insult anyone
> > personally but tried to polit[e]ly explain.
> Is it insulting to suggest that I would prefer not to work with you? Did I
>not state my belief that even people with a closed-mind can be reformed?
>Perhaps it was over the top to characterize as obtuse your firm and absolute
>stance against something that many others value. It is rather a harsh word
>and, since we are not known to one another, it was impolite. But not
>inaccurate.
You didn't write "I prefer not to work for Shai" but rather recomended everyone
avoid working for me. Thats an insult.
I think you are the one with the closed mind who already formed an opinion about
me and about (chuckle) my "third world country".
> Obtuse can mean "insensitive", and you seem that to me. It can also mean slow
>to perceive, and here again, your vituperative attacks upon a technique that
>others have employed profitably seemed to demonstrate a slowness to realize the
>value of the technique.
I never said I was sensitive, I don't claim to be.
I doubt I am slow to persive as I answered everything you have sent my way.
And people have deployed applications with COBOL, the fact that people want or
successfully use a technology does not make it appropriate to the Java languge.
> I did not find your comment that you would fire a person for using enums to be
>very polite. Have you ever been out of work? Can you imagine the distress
No, I worked hard and discussed issues with everyone of my bosses. No one ever
fired me. I think I know why they fired you though. I doubt a comment about
firing an employee I hired is impolite and mentioning this has nothing to
do with manners or netiquete, its just your own pet peeve.
>that would bring to such a person? And you would do this to somebody over a
>disagreement over a miniscule element of design? What if someone were to read
>your otherwise erudite comments and take you seriously? "Show of hands,
>people: Who would choose to work under these circumstances?".
Having worked under cluless bosses I always loved working under someone with
a strong sense of leadeship and technical ability. Sadly these cases were
very rare.
> > ENUM's are a solution for a problem that shouldn't exist in the first place
>
> a) perhaps these problems shouldn't exist, but they do
> b) such solutions are often more concise and efficient than the alternative.
I have yet to run into it once, give me a REAL example.
> > the application should handle these problems
> > with polymorphism and storage solutions.
> "May" handle these problems, not "should", not "must". It is impolite to
>state things unprovisionally. One convinces by dint of reason, not by demand.
>Better to coax one's readers into agreeing with you than to insist that they
>agree.
Fine, don't agree, but give me something to debate. I gave several examples
which you can either try to refute or try to give an example of your own instead
you choose to attack me personally... Which one of us is closed minded.
> Let's examine polymorphism (although, I think inheritence provides you with a
>stronger argument). Are these the alternatives?
>
> class foo {
> // Alternative 1
> // let A,B & C be legal enumerated values of the type variable.
> void method( enum type )
> {
> switch( type )
> {
> case A: methodA(); break;
> case B: methodB(); break;
> case C: methodC(); break;
> }
> }
>
> // Alternative 2
> method( ClassA a ){ }
> method( ClassB b ){ }
> method( ClassC c ){ }
> }
>
> It's impossible to state which of these solutions is better. One must know
>whether or not there are other data related to the types (data which are both
>relevant and available at the time the method is evoked). If I happen to have
>3 types of fully constructed objects, then yes, polymorphism is nice and ever
>so slightly more efficient than the switch statement (because the method
>address is indexed -- a quick lookup and jump -- rather than a series of
>comparisons and branches).
Polymorphisem can be much faster thanks to JIT improvements.
> But what if the type corresponds to a user's choice? Imagine a radio button
>in a dialog in which a customer selects which method he prefers to be
>contacted: email, phone, fax? Somewhere I will store each of these pieces of
A user selection will need to be mapped to an ENUM? Thats redundant. Have
a listener call the method directly.
>data, but not when I ask him to choose. And someday we may use this fact to
>generate an email, phone call or fax, but not today -- not when the user clicks
>"Okay" on the dialog box. Indeed, the GUI choice we solicit may not need to
>persist, but may have a lifetime shorter than the current "session". Must I
>store this choice as a class? Is there no reason to store this "type" as a
>simple integer (or, better yet, a typesafe enum!)?
Your storage choice will need to be mapped to your storage topology. If you
store to the database you can't store an ENUM and you will need to map it
back and forth. If you store with serialization (which is bad in its own) then
you hardly need an ENUM. Eitherway storing with ENUM's is mapping ENUM's back
and forth which is redundant.
> > Give me a single "real" problem that requires
> > ENUM's and cannot be solved in a better
> > way (where better is defined in terms of
> > generic, dynamic, performance, code size).
> Well, you give it yourself. Your Airplane class, for example, would be silly
>if the only distinguishing characteristic between airplanes was its type (or,
>as in my Printer example, its name).
Thats untrue with new JIT's as I have demonstrated.
> My rule of thumb is to attempt to collect the distinguishing aspects of
>varying "types of instances" (I'm purposely avoiding the use of the term class)
>until a class is required. A class is required when these instances need to
>contain not just data that can be stored in a table, but behavior (code) as
>well (and even then, when the behavior is trivial compared to the larger body
>of common behavior, or when not all instances require distinct behavior, I'm
>tempted to (gulp) keep a type variable).
Thats a C++ approach, bigger classes. Java allows smaller classes and follows
that approach there is nothing wrong with creating many classes.
> As for performance, type variables are usually going to be more efficient.
>Consider how efficient it is to define constant integers and make occasional
>comparisons to an integer value generated by an event external to our class (or
>database lookup or whatever). This compares favorably to the cost of loading
>just one other class (with the security checks etc). It's a negligible
>difference, but there had better be a reason for loading that class and perhaps
>constructing an object of its type beyond the elimination of a switch
>statement.
The cost of loading a class happens one time, but the JIT takes away the cost
completely which is not true regarding a switch statement which is much harder
to optimize away.
> Let's consider the 2nd example you give in your response to Valentin...
>
> class MyObject {
> public void myFunction(Enum param) {
> switch(param) {
> // this is a huge bottleneck in the project
> // since this might grow very large causing
> // both performance overhead and the need
> // for multiple developers to work on a single
> // large method
> }
> }
> }
>
> The key word here is "might". Such a switch statement might grow very large,
>but in many instances it will be known with near absolute certainty to remain
>small. Must I abandon the obvious and simple switch statement to satisfy a
>doctrinaire design technique? I must if I want to work for you, apparently.
Its not simpler than the other approaches once you wire your mind to work
in an object oriented way. These other ways don't require extra code or
cost in performance, why write something that might not scale when you
can use the same energie to write something that will scale.
> > A better way is to split this type of functionality to
> > multiple methods and classes.
>
> You see, this is the kind of absolute, non-provisional statement that gets my
>goat. Sometimes it is better to invent classes and invoke virtual methods.
>Sometimes. Not always.
There aren't many absolutes, I have yet to see a single use of ENUM that will
give any advantage whatsoever. Up to that point in time there is a very strong
reason for me to assume that it is unnecessary. Since many people tried to
convince me and failed this has turned to an absolute, so far you are doint very
badly as a debate, people came up with much better examples.
> Okay, now for your 3rd example...
>
> >>> 3. You need to perform code according to a numeric value
> and have a single entry point.
>
> public class LoadFile {
> private void loadObjectFromXMLData(int value) {
> switch(value) {
> case FIRST_TYPE:
> // perform code
> }
> }
> }
>
> should be written as a map lookup
> public class LoadFile {
> private void loadObjectFromXMLData(int value) {
> ((Runnable)actionMap.get(new Integer(value))).run();
> }
> }
> <>
> Now this one takes the cake. Do yourself a favor and next time you're
>debugging code (I assume you still have to do that, sometimes managers move
>beyond this and lose touch with the vagaries of the tasks assigned to people
>"under" them). Do yourself a favor and step into the get() routine of, say,
>HashMap. Watch as it computes the hash value of the Integer value (and don't
>forget that the Integer object references the int value indirectly and
>generates a reference which has to be managed for later garbage collection).
>Watch as it runs through the for loop looking for a match. This will not,
>under ANY circumstances result in significant performance boost -- and for
>sufficiently small sets of enumerated values, the switch statement will win the
>race hands down (and int's may be stored on the stack and are never separately
>garbage collected).
This is mostly removed by a smart JIT. Integer is final and the JIT has special
treatment for the String/Number classes. The map lookup code is inlined into
the method and the actual resulting assembler code should be as efficient if
not more so as the switch statement. Better yet, if the keys are sequential you
can avoid the map and use an array for the mapping and gain much better
performance than that.
> > While this is just as verbose as a switch statement, it
> > has the advantage of being dynamically extensible, and
> > easier to extend as a part of an API.
> The static solution has the advantage of being determinate and anybody who
>debugs on a regular basis can appreciate the advantage of determinacy for
>debugging. One can set a breakpoint on a case, one cannot do so on a get() --
>well, you can, but then you get to enjoy the trip through the lookup process on
>your way to the execution of the run() method.
You can set the breakpoint in the run() method just as you can on a particular
case. There is no point in debugging a map implementation since it works
perfectly, if you need to see the value the method received then you can break
on the method itself and then on the apporiate runnable. Hardly trouble at all.
> But I suppose your suggesting that each case is replaced by a unique class
>whose sole purpose is to encapsulate the behavior of the case block. I guess I
>find this approach more verbose. Even though I have used this wherever
>necessary, I would hardly suggest that it was the only acceptable approach!
>And to do so for the Runnable example you give (admittedly, contrived for its
>simplicity, so it can be forgiven for its simplicity) is preposterous.
I said that this is a simple example but I never claimed it was "the" solution.
In fact I hardly use this solution myself, and usually settle for the first
two solutions.
You still haven't proven a single point.
1. Its just as fast as a case statement depending on the type of JIT you use.
2. Its the same amount of code when using inner classes.
3. Its just as easy to debug.
4. Its MORE generic and easier to extend.
> Moreover, the switch statement is encapsulated, the actionMap solution could
>potentially be spread throughout the source code (potentially, I didn't say it
>would be done intentionally). In fact, one could implement the Runnable
>interface in any library, including those for which you have no source code and
>for which you haven't a clue as to its side effects. Obviously, you would
>attempt to eliminate this problem by restricting access to the actionMap (you
>would restrict access to the actionMap, wouldn't you?).
I would restrict access to the action map for subclasses only via an add method.
Dynamic code comes with a price of allowing bugs to come from all over the code.
I said that the Map can scale if needed to be dynamic, I wouldn't expose it
until the moment I need to expose it.
> Please, I beg you. Abandon your miscreant creed. You will not go to hell for
>using a switch statement. I won't go so far as to suggest that example 3 is
>lunacy, but it is certainly bizarre in the face of any simple set of enumerated
>values -- which most are! Each subsequent invocation of this method could
>cause a new class to be loaded -- how is that better than a handful of
>branches?
No the new classes will be created on startup not on invocation...
> So, let me say this politely, you have a long way to go before you have PROVEN
>your point and I feel sorry for anybody who actually gets fired for disagreeing
>with you. In fact, to recap my original point, I feel sorry for anybody who
>has to work under that Draconian threat.
You have a long way to go before you can PROVE your point.
I wouldn't write what I feel about you, that would be impolite. -
RE: I remain unconvinced of the danger of Enumerated types[ Go to top ]
- Posted by: Cameron Zemek
- Posted on: July 13 2003 23:19 EDT
- in response to Shai Almog
Okay this thread is dead and unfortunately I can't email Shai Almog. But here is my 2 cents regarding enums. I will take TableModelEvent from Swing as an example:
public class TableModelEvent extends java.util.EventObject
{
/** Identifies the addtion of new rows or columns. */
public static final int INSERT = 1;
/** Identifies a change to existing data. */
public static final int UPDATE = 0;
/** Identifies the removal of rows or columns. */
public static final int DELETE = -1;
// snip
/**
* Returns the type of event - one of: INSERT, UPDATE and DELETE.
*/
public int getType() { return type; }
}
In the above code the type is an enum with a value of INSERT, UPDATE or DELETE. Enums help to ensure that a valid value is given and hides the underlying value. Now if I have code that listens to table model events I would have
public void tableChanged(TableModelEvent e){
int firstRow = e.getFirstRow();
int lastRow = e.getLastRow();
int col = e.getColumn();
if(e.getType() == TableModelEvent.INSERT){
System.out.println("Rows (" + firstRow + "," + lastRow
+ ") were inserted");
}else if(e.getType() == TableModelEvent.UPDATE){
if(col == TableModelEvent.ALL_COLUMNS){
System.out.println("Rows (" + firstRow + "," + lastRow
+ ") were updated");
}else{
System.out.println("Cell (" + firstRow + "," + col + ") was updated");
}
}else if(e.getType() == TableModelEvent.DELETE){
System.out.println("Rows (" + firstRow + "," + lastRow + ") were deleted");
}
}
Now for your suggestions on how to avoid using enums.
<Shai>
1. If indeed it is only a name then I would simply create a printer with a
string for name (but I realize this is not where you were going).
</Shai>
The above is using a property to separate between the different types of event. That type being an int. Using an enum type would be safer and makes it clearer. Eg. if getType() returned TableEventType then the compiler enforces it to be INSERT, UPDATE or DELETE.
<Shai>
2. Subclassing has a minor loading cost in Java, however this cost occurs
only once and the gained performance is huge. Both Sun and IBM JIT's perform
virtual method inlining which COMPLETELY removes the cost of a virtual method
call making it as fast as a C++ inline method.
</Shai>
Using subclassing for event types you would have:
public abstract class TableModelEvent{
// same as TableModelEvent from swing but without type property
}
public class InsertTableModelEvent extends TableModelEvent{ }
public class DeleteTableModelEvent extends TableModelEvent{ }
public class UpdateTableModelEvent extends TableModelEvent{ }
If I want to override a method in TableModelEvent to apply to all TableModelEvents then your out of luck, since you can't make the different types change which class they subclass from. Additionally, since Java only has single inheritance you don't allow TableModelEvent to be subclassed for other reasons.
So in the case of TableModelEvent, using subclassing instead of enums reduces flexibility and increases the complexity (in construction logic and need to be aware of class hierarchy). Using inheritance for the above purpose also violates the Liskov Substitution Principle since table listeners are treating each table event differently.
I would also like to point out that using polymorphism is the inverse of a switch statement (when used properly which is not the case above).
OO approach:
public void do(Thing t){
t.do();
}
public class Type1 implements Thing{
public void do(){ /* do stuff for type1 */ }
}
public class Type2 implements Thing{
public void do(){ /* do stuff for type2 */ }
}
public class Type3 implements Thing{
public void do(){ /* do stuff for type3 */ }
}
Procedural approach:
public void do(Thing t){
switch(t.type){
case type1:
// do stuff for type1
break;
case type2:
// do stuff for type2
break;
case type3:
// do stuff for type3
break;
}
} -
Prefer not to work[ Go to top ]
- Posted by: Valentin Sliouniaev
- Posted on: April 17 2003 05:21 EDT
- in response to Robert White
I've just re-read both Joshua's book and the enum proposal. Ability to add methods to enum constants seems even neater than a talking frog! :-)
have fun,
--VS. -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Valentin Sliouniaev
- Posted on: April 11 2003 15:21 EDT
- in response to Shai Almog
"1. ENUM's are the absolute worst. They make my blood boil and every
programmer I see using them (in C++ as well) is fired on the spot.
Programmers who try to use ENUM "alternatives" such as small classes
or interger constants will never get promoted and need serious help
in understanding object oriented design. No OO language needs ENUM's."
Could you please elaborate? Do you use plain integer literals or perhaps a class for each value of the enum? I am aware of problems with both integer constants and enum classes, so there is all more reason to make them part of the language - to allow both more efficient and more robust implementation.
Also, using symbolic names were considered a good practice since the beginning of computer programming (see Knuth's volume 1). "Integer constants" are the same as 'EQU' in assemblers, '#define' in C, 'const atype' in C++..., etc. I am confused...
thanks,
--VS. -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 11 2003 16:53 EDT
- in response to Valentin Sliouniaev
Valentin,
there are several cases in which people use ENUM's, here are some
examples:
1. To indicate an attribute of an object (this code is somewhat
C++ish since it relies on ENUM's being int's:
class Aircraft {
int type;
private void doStuff() {
if(type & F_15) {
....
}
}
}
This is real, I worked on a flight simulator that had a hard
time since we needed to add an ENUM for each craft that completely
botched the build everytime.
A better solution, more extensible and efficient one is to have
class Aircraft {
public boolean isF15();
private void doStuff() {
if(isF15()) {
....
}
}
}
2. Another way to use ENUM's is as verbose parameters.
The problem is that your code turns into a mess dealing
with these ENUM's. So:
class MyObject {
public void myFunction(Enum param) {
switch(param) {
// this is a huge bottleneck in the project
// since this might grow very large causing
// both performance overhead and the need
// for multiple developers to work on a single
// large method
}
}
}
A better way is to split this type of functionality to
multiple methods and classes.
3. You need to perform code according to a numeric value
and have a single entry point.
public class LoadFile {
private void loadObjectFromXMLData(int value) {
switch(value) {
case FIRST_TYPE:
// perform code
}
}
}
should be written as a map lookup
public class LoadFile {
private void loadObjectFromXMLData(int value) {
((Runnable)actionMap.get(new Integer(value))).run();
}
}
I just used runnable as a simple interface but obviously
if you have more parameters you can use any type of interface.
While this is just as verbose as a switch statement, it
has the advantage of being dynamically extensible, and
easier to extend as a part of an API. -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Valentin Sliouniaev
- Posted on: April 11 2003 18:05 EDT
- in response to Shai Almog
Hello Shai,
thank you. Good examples. Some comments.
>>> The 1st: This is not an enum.
When it is down to logical '&', it is more like a bit set rather than an enum. In C++ a better alternative is to use bit fields. A line like
if (jet && supersonic && engines==2) ...
may compile into three (two in some cases) machine commands. In Java isYyyy() is a good alternative, only alas, I am afraid that the above and
jet = 1;
supersonic = 1;
engines = 2;
won't compile into a few bytes of native code (all three assignments may compile into a single instruction). Perhaps not important if you deal with only a few jets in a game, but it may be if you work with characters in a document.
>>> The 2nd: this is just moving the responsibility up one level.
Who is to decide which of the few methods to call? Of course if the constant is passed as the argument it may make sense; but what if we pass a uniform object, which has certain property relevant only to the callee?
For example, jets should be process()-ed separately from turbo-props, but the caller isn't interested in what the internals of the process() method do. Why the caller should decide which one to call: processAJet() or processATurboProp()?
(I suspect that it would be impossible to use class hierarchy inside process() to separate onces from the others, since multiple properties like that may need to be provided. Anyway, that would be just another way of encoding enums - with class hierarchies.)
>>> The 3rd: Does not address the issue.
This is more about how to get rid of the 'switch' statement rather than how to encode that 'value' parameter. The value needs to be provided by the caller anyway. Is it just '5' or Color.RED? Is it '3' or Calendar.APRIL?
This is not so apparent when processing the data, but when generating the data, it becomes essential. That is, I'd rather use a symbolic constant or an enum to write (in about 100 different places):
... = new Fly(Fly.JET, Fly.CIVILIAN);
than
... = new Fly(3,2);
and enums just add more type-safety, for the once who mixes it like this:
... = new Fly(Fly.CIVILIAN, Fly.JET);
As for the "getting rid of the switch" technique - you still need to set up the map. Is it done like this:
actionMap.put(1, ...);
actionMap.put(2, ...);
or
actionMap.put(Fly.TURBOPROP, ...);
actionMap.put(Fly.JET, ...);
?
And what happens with the code if the number is not in the map?..
regards,
--VS.
PS. Ironically, in the language, which has no pointers one of the most frequent exceptions is 'NullPointerException', like in the following naive piece of code:
if (request.getAttribute("seperate").equals("false")) ...
:-| -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 11 2003 18:38 EDT
- in response to Valentin Sliouniaev
thank you. Good examples. Some comments.
Thank you for a plesant discussion, last time I had this discussion was on
the JL and it turned into a slight flamewar which was only resolved in private
E-Mail (resolved with a disagreement though).
> >>> The 1st: This is not an enum.
>
> When it is down to logical '&', it is more like a bit set rather than an enum. In C++ a better alternative is to use bit fields. A line like
>
> if (jet && supersonic && engines==2) ...
>
> may compile into three (two in some cases) machine commands. In Java isYyyy() is a good alternative, only alas, I am afraid that the above and
>
> jet = 1;
> supersonic = 1;
> engines = 2;
>
> won't compile into a few bytes of native code (all three assignments may compile into a single instruction). Perhaps not important if you deal with only a few jets in a game, but it may be if you work with characters in a document.
I disagree, with JIT's this would work rather well. Since you hardcode return
true within the overriden method you can get the advantages of virtual method
inlining and have NO COST of evaluation and complete removal of the else code!!
This means the JIT in this case can EASILY erase a completely redundant if.
While this could potentially be done by a really inteligent JIT in the case of
a bitwise & operation. I doubt this will even be the case.
> >>> The 2nd: this is just moving the responsibility up one level.
>
> Who is to decide which of the few methods to call? Of course if the constant is passed as the argument it may make sense; but what if we pass a uniform object, which has certain property relevant only to the callee?
>
> For example, jets should be process()-ed separately from turbo-props, but the caller isn't interested in what the internals of the process() method do. Why the caller should decide which one to call: processAJet() or processATurboProp()?
This example would fall into the 3rd example I gave. This case would indeed
just move the switch bloat to a different method.
> >>> The 3rd: Does not address the issue.
>
> This is more about how to get rid of the 'switch' statement rather than how to encode that 'value' parameter. The value needs to be provided by the caller anyway. Is it just '5' or Color.RED? Is it '3' or Calendar.APRIL?
Why would you have a Calendar.APRIL?
This is the exact use case of the second option, Calendar is widely regarded
as one of the worst API's in Java.
> This is not so apparent when processing the data, but when generating the data, it becomes essential. That is, I'd rather use a symbolic constant or an enum to write (in about 100 different places):
>
> ... = new Fly(Fly.JET, Fly.CIVILIAN);
>
> than
> ... = new Fly(3,2);
Me too, I would write Fly.createCivilianJet();
> and enums just add more type-safety, for the once who mixes it like this:
>
> ... = new Fly(Fly.CIVILIAN, Fly.JET);
All of the knowledge about fly should be within the class and related package
protected interfaces. By using the ENUM/Constants you expose implementation
detail. I don't mine if createCivilianJets() has hardcoded numbers within it
since its only referenced within the class and is under control. Constants break
the very notion of control. private constants are OK in my book though ;)
> As for the "getting rid of the switch" technique - you still need to set up the map. Is it done like this:
>
> actionMap.put(1, ...);
> actionMap.put(2, ...);
>
> or
>
> actionMap.put(Fly.TURBOPROP, ...);
> actionMap.put(Fly.JET, ...);
As I said this is just as verbose, however I can do it by
protected void addMapedAction(String key, Runnable action);
and then have subclasses register behavior which is what
I refered to as the dynamic nature allowing us to redistribute
the code. Better yet, the class names can be placed in a
property file and loaded dynamically to allow extentions
to your code... (we did this in many projects).
> And what happens with the code if the number is not in the map?..
I specifically wrote it to get a NullPointerException, which is what
I usually want in this case. However sometimes I check for null before
invoking if I'm interested in other functions.
> PS. Ironically, in the language, which has no pointers one of the most frequent exceptions is 'NullPointerException', like in the following naive piece of code:
>
> if (request.getAttribute("seperate").equals("false")) ...
Java has only pointers and no stack objects ;) -
Is it bad to have good ideas?[ Go to top ]
- Posted by: David McCoy
- Posted on: April 11 2003 19:43 EDT
- in response to Shai Almog
This is not so apparent when processing the data, but when generating the data, it becomes essential. That is, I'd rather use a symbolic constant or an enum to write (in about 100 different places):
>
> ... = new Fly(Fly.JET, Fly.CIVILIAN);
>
> than
> ... = new Fly(3,2);
Me too, I would write Fly.createCivilianJet();
> and enums just add more type-safety, for the once who mixes it like this:
>
> ... = new Fly(Fly.CIVILIAN, Fly.JET);
This seems to be more of a sylistic difference. Personally, I wouldn't want to write several methods that all do the same thing and differ in such a way. Would you have completely different methods or would you have the "create" pass the ints to the constructor?
What happens as you add plane types? Would you create more methods? Wouldn't this be a maintenance nightmare? Everytime you add or subject plane types you have to create or remove a method.
I definitely don't like the static import for reasons of readability. As for the generics, even Blooch stated that he believes that 90% of the collections are used for String(and most likely objects of the same type), so I personally wouldn't mind a little less casting for such a small price.
But I don't agree with your reasons for not having/using Enums. At best, I see a difference in style that you enforce on your subordinates(which is the bosses right, I guess), but I still haven't seen a reason that is compelling to me against taking a well worn, well used pattern, and easing our labors.
Great discussion, though!! -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 12 2003 02:56 EDT
- in response to David McCoy
This seems to be more of a sylistic difference. Personally, I wouldn't want to
>write several methods that all do the same thing and differ in such a way.
>Would you have completely different methods or would you have the "create" pass
>the ints to the constructor?
This is way more than a stylistic difference.
1. You have control over the point of entry for each use case.
2. You can factor methods down to subclasses the moment the parent
class becomes too big.
With ENUM's you have the same problems but without a real solution, sure
you can factor some of the huge switch statement to other methods/classes
but then they are tightly coupled and need to know about each other. In
a case of subclassing and adding a factory method we don't cement anything.
> What happens as you add plane types? Would you create more methods? Wouldn't
>this be a maintenance nightmare? Everytime you add or subject plane types you
>have to create or remove a method.
As I said, this can be easily factored into subclasses which is not the
case for ENUM's.
> I definitely don't like the static import for reasons of readability. As for
>the generics, even Blooch stated that he believes that 90% of the collections
>are used for String(and most likely objects of the same type), so I personally
>wouldn't mind a little less casting for such a small price.
I'll repeat my opinion about generics:
"People expect great changes for genrics but frankly generics will make the
really easy things (single type collections) very slightly simpler, while
not making a difference to the complicated things (polimorphic collections).
Furthermore the fact that a compatible implementation that actually works
is technically impossible adds a level of complexity that makes the change
completely impossible."
Generics while maintaining compatability WON'T work!!!
> But I don't agree with your reasons for not having/using Enums. At best, I see
>a difference in style that you enforce on your subordinates(which is the bosses
>right, I guess), but I still haven't seen a reason that is compelling to me
>against taking a well worn, well used pattern, and easing our labors.
I don't see a single way in which ENUM's ease your life other than using Java
as C. As I demonstrated every problem solvable by ENUM's is solveable by OO
code of roughly the same (or lower) complexity, which is both more generic,
dynamic and has better performance (at least in potential, depending on JIT). -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Valentin Sliouniaev
- Posted on: April 11 2003 20:05 EDT
- in response to Shai Almog
Hello Shai,
> I disagree, with JIT's this would work rather well. Since you hardcode
> return true within the overriden method you can get the advantages of
> virtual method inlining and have NO COST of evaluation and complete
> removal of the else code!!
> This means the JIT in this case can EASILY erase a completely redundant if.
IMHO, hardly so if you scan thousands of different characters in a single loop... do you have more info about how it works?
> >
> > ... = new Fly(Fly.JET, Fly.CIVILIAN);
> >
> > than
> > ... = new Fly(3,2);
> Me too, I would write Fly.createCivilianJet();
So, I have a form, which allows the user to register a plane. It has two drop downs: engine type and plane type:
enum {glider, spring, pedal, prop, turboprop, turbofan, jet, rocket};
enum {civilian, military, vintage};
Questions:
- which part of the code is responsible for converting codes into text?
- which part of the code is responsible for parsing user input into engine type and plane type?
- how do I map the two entered values to 24 createXxxxYyyy()?
- how does a third-party method, e.g. sendEMailToRelevantAuthority(), determine if a plane is civilian or military?
> Java has only pointers and no stack objects ;)
Which is a pity, IMHO. Such thing as value objects (e.g. peers of primitive types) would greatly help to improve performance. E.g why can't we allocate a Complex or a Point on the stack, along all local ints and doubles? Well perhaps it might be possible to optimise it taking immutability in consideration?..
thank you,
--VS. -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Mike Spille
- Posted on: April 11 2003 20:19 EDT
- in response to Valentin Sliouniaev
\Sliouniaev\
So, I have a form, which allows the user to register a plane. It has two drop downs: engine type and plane type:
enum {glider, spring, pedal, prop, turboprop, turbofan, jet, rocket};
enum {civilian, military, vintage};
Questions:
- which part of the code is responsible for converting codes into text?
- which part of the code is responsible for parsing user input into engine type and plane type?
- how do I map the two entered values to 24 createXxxxYyyy()?
- how does a third-party method, e.g. sendEMailToRelevantAuthority(), determine if a plane is civilian or military?
\Sliouniaev\
This is a rather poor example of enum usage.
A more typical example would be something like a 'state' variable in a state machine, an option variable, and things of that nature. As another poster mentioned, look at the instances in existing Java standard libraries that use integers, and you'll see more realistic examples. In cases like those, an enum would give you better type safety and not really cost much of anything. It's also useful if you happening to be using bitfields. The underlying code might need to break the enum safety and-ing and or-ing, but an API interface could provide something like:
setFlag (Enum X)
boolean flagIsSet (Enum X);
\Sliouniaev\
Which is a pity, IMHO. Such thing as value objects (e.g. peers of primitive types) would greatly help to improve performance. E.g why can't we allocate a Complex or a Point on the stack, along all local ints and doubles? Well perhaps it might be possible to optimise it taking immutability in consideration?..
\Sliouniaev\
I think a JIT can do this today BUT an optimizer generally won't do it if you pass a reference to an object to another method on another object. Once you go outside of the JITs current compilation scope, it can't know what that method is doing, and specifically can't know if you're holding a reference to the pased in object. E.G.
Point point = Point (1, 5); // Assume this is stack allocated
foo.doSomething (point);
In the above example, you don't know if foo.doSomething() is going to try to hang on to that reference. If it did and you allocated it on the stack, then returned from the allocating method and the object was later dereferenced - wham!
Returning local objects also brings up C++ bugaboos like temporaries and their lifetimes and copy constructors and the rest.
I don't see how immutability applies - the problem is references and object lifetime.
Also - keep in mind under the Java 1.4 allocator & GC system, heap allocation is really, really cheap. The only savings would be less garbage to collect, and the 1.4 GC is ridiculously fast on the new generation. This is little comfort to those who haven't yet gone to Java 1.4, but in time most will and will gain the benefits.
-Mike -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Valentin Sliouniaev
- Posted on: April 12 2003 20:01 EDT
- in response to Mike Spille
\Spille\
> ... It's also useful if you happening to be using bitfields.
> The underlying code might need to break the enum safety
> and-ing and or-ing, but an API interface could provide
> something like:
>
> setFlag (Enum X)
> boolean flagIsSet (Enum X);
>
\Spille\
It is not an enum, it's a bit set. Set of possible values for a bit set is very much different from that of an enum. In addition, set of operations is completely different, too. I would not rather mix them together.
\Spille\
> Returning local objects also brings up C++ bugaboos like
> temporaries and their lifetimes and copy constructors and
> the rest.
>
> I don't see how immutability applies - the problem is
> references and object lifetime.
\Spille\
If an object is immutable, you could return a copy of it the moment it goes out of local scope (stored in member data or retuned; it's ok to pass into another method).
\Spille\
> Also - keep in mind under the Java 1.4 allocator & GC system,
> heap allocation is really, really cheap. The only savings would
> be less garbage to collect, and the 1.4 GC is ridiculously fast
\Spille\
Perhaps. I also hope that it improves locality of reference to all of my complex numbers in rectangular matrixes when I multiply them. In FORTRAN and C that was ridiculosly cheap.
regards,
--VS. -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Mike Spille
- Posted on: April 12 2003 23:14 EDT
- in response to Valentin Sliouniaev
\Sliouniaev\
It is not an enum, it's a bit set. Set of possible values for a bit set is very much different from that of an enum. In addition, set of operations is completely different, too. I would not rather mix them together.
\Sliouniaev\
It's a bitset in the hidden internals of the class. At the API level, it's an enum that enforces type safety and valid values. And such uses of enums in other languages is _not_ at all uncommon.
\Sliouniaev\
If an object is immutable, you could return a copy of it the moment it goes out of local scope (stored in member data or retuned; it's ok to pass into another method).
\Sliouniaev\
Assuming we don't want to get into the lifetime-of-tempoaries bugaboo of C++, then that "copy" is a heap allocation - in other words, you completely lose the benefit of the local object. Likewise - if you always pass in a copy when doing a member invocation, you again lose the value - you must do a heap allocation.
The whole point of local stack objects is they're automatically "collected" when you pass out of its local scope. You're not generating garbage. The minute you introduce copy-the-object-to-the-heap, you've lost the whole point of the exercise.
\Sliouniaev\
[On java 1.4 GC..]
Perhaps. I also hope that it improves locality of reference to all of my complex numbers in rectangular matrixes when I multiply them. In FORTRAN and C that was ridiculosly cheap.
\Sliouniaev\
No, this could potentially be slightly worse in Java 1.4, since objects can pretty quickly migrate through various generations (e.g. they physically move). And the array semantics of Java haven't changed either. But you can always manually index a single dimensional array as if it were multi-dimensional, so you're accessing a continugous space. In fact I'd be surprised if any heavily math intensive code wasn't already doing this.
-Mike -
Bit fields are not enums[ Go to top ]
- Posted by: Valentin Sliouniaev
- Posted on: April 13 2003 08:51 EDT
- in response to Mike Spille
It's a bitset in the hidden internals of the
> class. At the API level, it's an enum that
> enforces type safety and valid values.
> And such uses of enums in other languages
> is _not_ at all uncommon.
Yes, right, unfortunately it is not uncommon.
However if you look at the history of the thing, it started with #define-s for bit fields:
#define PETROL 0x0001
#define SPORTS 0x0010
#define RACING 0x0020
#define FAMILY 0x0030
...
#define TYPE_MASK 0x01F0
...
if ( (flags & TYPE_MASK) == FAMILY && (flags & PETROL)) ...
then somebody thought "outside the box" and invented
enum { PETROL=1, SPORTS=16, ... FAMILY, TYPE_MASK=496 }
where a better way of using it is
enum CarType { SPORTS, ... FAMILY }; // declare set of values
class ... {
int isPetrol:1;
:3;
CarType carType :5;
};
or better yet, allow the compiler to pack small enums into bit fields.
There is no need to pack independent single- or small-bit variables into a single enum. Enum is a set of possible values for a single variable.
Unfortunately, this slipped into C#, too, apparently because they wanted to have some independent variables packed into one int, but couldn't do the bit fields. Thinking inside the box again...
regards,
--VS. -
Bit fields are not enums[ Go to top ]
- Posted by: Mike Spille
- Posted on: April 13 2003 14:44 EDT
- in response to Valentin Sliouniaev
\Sliouniaev\
There is no need to pack independent single- or small-bit variables into a single enum. Enum is a set of possible values for a single variable.
[...]
Unfortunately, this slipped into C#, too, apparently because they wanted to have some independent variables packed into one int, but couldn't do the bit fields. Thinking inside the box again...
\Sliouniaev\
I see what you're getting at, but I think you're defining what an enum is in an overly-narrow way. And the value judgements of "thinking inside the box" and "thinking outside of the box" really aren't very useful here :-/
You appear to be saying that adding a language feature for bitfields is better than using enums to achieve the same goal. I agree it adds some convenience - at the cost of even more language complexity, and some strange language rules (see the complete C and C++ rules on bitfields for details). Honestly, I don't see why you seem to dislike the concept of bitfields, and then start advocating use of bitfields (which is really a variant on the enum concept).
My feeling is that enums add some convenience to the language, and a bit of additional type safety, with little added complexity to the language. I fail to see how this is a bad thing. And I personally prefer to use enums when doing bitfield-like operations, because often those bitfield values map to something external to the VM. Seeing the explicit value in an enum points to exactly what a value means. Using bitfields, you have to count how far into a bitfield a value is to try to figure out its ultimate value.
-Mike -
Bit fields are not enums[ Go to top ]
- Posted by: Valentin Sliouniaev
- Posted on: April 13 2003 16:51 EDT
- in response to Mike Spille
Very good points: external representation and adding complexity.
I still find using bitwise ops to get at bitfield values a bit old fasioned (it is C, not even C++). It also exposes implementation of the object to the rest of the universe. Compare:
MyFlags flags = new MyFlags(0xCABA);
if (flags.canFly()) ...;
with
int flags = 0xBEDA;
if ((flags & MyFlags.CANFLOAT) != 0) ...; // everywhere
and (again, every time i need this value):
int nEngines = flags.getNumEngines();
int nEngines = (flags & MyFlags.ENGINES_MASK) >> MyFlags.ENGINES_SHIFT;
I would keep enums as just a plain set of values for a single variable. The bit fields IMHO would be better done as an ordinary class (not enum), which does the bitwise bits inside itself, but packs and unpacks the bits to values via '{int|boolean} getXxx()' and '{void|MyEnum} setXxx()'.
Oops, I just realised that an instance of that simple class is an object, not a value. It adds a level of overhead, however negligible. What could be better than a simple sweet short value type with a set of operations on it? I keep missing it (the value type), but alas, can't be done in Java!
regards,
--VS. -
Bit fields are not enums[ Go to top ]
- Posted by: Mike Spille
- Posted on: April 13 2003 19:57 EDT
- in response to Valentin Sliouniaev
\Sliouniaev\
I still find using bitwise ops to get at bitfield values a bit old fasioned (it is C, not even C++). It also exposes implementation of the object to the rest of the universe. Compare:
MyFlags flags = new MyFlags(0xCABA);
if (flags.canFly()) ...;
with
int flags = 0xBEDA;
if ((flags & MyFlags.CANFLOAT) != 0) ...; // everywhere
\Sliouniaev\
That's not at all what I advocated. If you go back to an earlier post of my in this thread, you'll see my example was:
public void isSet (MyEnum flag);
public void setFlag (MyEnum flag);
public void clearFlag (MyEnum flag);
So in my code I would say:
if (obj.isSet (CANFLOAT)) ....
This hides the underlying bitfield implementation, and enums means people can't pass in meaningless junk. It seems to me at this point you're just making up objections out of sheer contrariness....
\Sliouniaev\
I would keep enums as just a plain set of values for a single variable. The bit fields IMHO would be better done as an ordinary class (not enum), which does the bitwise bits inside itself, but packs and unpacks the bits to values via '{int|boolean} getXxx()' and '{void|MyEnum} setXxx()'.
\Sliouniaev\
You mean like my examples above? They use enums, give you type safety, mean you avoid doing bit operations all over your code, and are convenient. What more do you want?
\Sliounaev\
Oops, I just realised that an instance of that simple class is an object, not a value. It adds a level of overhead, however negligible. What could be better than a simple sweet short value type with a set of operations on it? I keep missing it (the value type), but alas, can't be done in Java!
\Sliouniaev\
I'm not sure what you mean by "value type". How does this differ from an object? It almost sounds like you're talking about a single piece of data (the value?) that has behavior attached to it. Sounds amazingly like an object to me.
Perhaps you mean "a single piece of data sitting on the stack". In that case, no you can't do that. You pay for "a level of overhead", which really and truly is negligible in most cases. What you get in return are guarantees that your program won't crash, and that you don't have to navigate complex language rules to figure out what the compiler's going to do in certain situations.
Back to the idea of isFlagSet(), setFlag(), etc - if you declare these as final a JIT may inline these calls. The only overhead will be an object dereference to get to the value (e.g. this.value, object.value). If you believe this overhead is too high, then you probably shouldn't be using _any_ object oriented language at all.
Seriously - you seem uninterested in seeing solutions that work, you just want to show how Java is speed crippled no matter what people say.
-Mike -
Bit fields are not enums[ Go to top ]
- Posted by: Valentin Sliouniaev
- Posted on: April 13 2003 21:25 EDT
- in response to Mike Spille
That's not at all what I advocated. If you go back
> to an earlier post of my in this thread, you'll see
> my example was:
I see, my apologies, this is a nice way of doing it.
regards,
--VS. -
Value objects[ Go to top ]
- Posted by: Valentin Sliouniaev
- Posted on: April 13 2003 21:52 EDT
- in response to Mike Spille
I'm not sure what you mean by "value type". How does this
> differ from an object? It almost sounds like you're talking
> about a single piece of data (the value?) that has behavior
> attached to it. Sounds amazingly like an object to me.
I indeed thought of "value objects". The difference is that they are allocated the same way as integers.
For example, they are parts of the containing object, not separate blobs in memory. If I aggregate a Point and another Point and Flags and an Enum into a Shape, I still have a single object in memory, not five. Makes some difference if many such Shapes are required.
> ... etc - if you declare these as final a JIT may inline
> these calls ...
> ...
> Seriously - you seem uninterested in seeing solutions that
> work, you just want to show how Java is speed crippled no
> matter what people say.
Yes. I even dare say that JIT itself is an overhead. :) As far as I remember, the original solution used to store JIT-ted code and re-use it later.
(Well, seriously, I do like your bitfield with enums solution.)
best regards,
--VS. -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Valentin Sliouniaev
- Posted on: April 13 2003 09:21 EDT
- in response to Mike Spille
Mike wrote:
> Assuming we don't want to get into the lifetime-of-
> tempoaries bugaboo of C++, then that "copy" is a
Why not re-use a huge experience of C++ in a good way?
> heap allocation - in other words, you completely
> lose the benefit of the local object. Likewise -
> if you always pass in a copy when doing a member
> invocation, you again lose the value - you must
> do a heap allocation.
I can either copy the value onto the stack again or pass a reference to the immutable original which is allocated earlier on the stack. If the called method is not passing the variable outside, no copying is necessary: the caller's stack will exist for the lifetime of the callee.
Another advantage is that value objects can be packed into a continuous area in memory, which improves locality of reference and reduces working set (thus improving co-existence of multiple programs in memory). As long a reference to an isolated element inside the array is not passed out, there is no need to allocate a copy on the heap.
> The minute you introduce copy-the-object-to-the-heap,
> you've lost the whole point of the exercise.
True, but it doesn't invalidate the need for stack allocation.
> But you can always manually index a single dimensional
> array as if it were multi-dimensional, so you're
> accessing a continugous space. In fact I'd be surprised
> if any heavily math intensive code wasn't already doing
> this.
Yep, multiplying matrices of complex numbers is an easy exersise in using The Simple Language. Oh, only two-dimensional arrays are not supported and infix notation which we learned in primary school isn't either.
Well, I guess this is not what one should be concerned of while developing for the server side. No more stupid comments. It's been fun though...
thanks,
--VS. -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Mike Spille
- Posted on: April 13 2003 15:06 EDT
- in response to Valentin Sliouniaev
Mike wrote:
> Assuming we don't want to get into the lifetime-of-
> tempoaries bugaboo of C++, then that "copy" is a
\Sliouniaev\
Why not re-use a huge experience of C++ in a good way?
\Sliouniaev\
I wouldn't call it a good experience. It's a continual source of confusion to newbies, many developers continually use them incorrectly and get random crashes, and dealing with temporaries and their lifetimes is a big chunk of the complexity in the C++ standard. And all of this confusion and complexity exists strictly because of the decision to support stack-based objects.
\Sliouniaev\
I can either copy the value onto the stack again or pass a reference to the immutable original which is allocated earlier on the stack. If the called method is not passing the variable outside, no copying is necessary: the caller's stack will exist for the lifetime of the callee.
\Sliouniaev\
The compiler cannot accurately determine the lifetime of an object. The best it can do is try to play tricks with temporaries to extend the lifetime of such objects. Unfortunately, ultimately the stack area where the temp lives (or the original object) _is_ going to go out of scope, and any hapless programmer hanging onto such a reference is going to effectively dereference an object that no longer physically exists.
Once again - immutable or not, the issue is references. If someone holds onto a reference to an object, the compiler generally _cannot know_ how long that reference is going to be held onto. When this happens, the compiler has two choices - stick with stack based object and hope for the best (usually resulting in corrupted data or an outright crash), or moving the object to the heap. In the former scenario, you've completely violated Java's guarantees and JVMs are going to be crashing left and right. In the latter scenario, you've ended up with a heap allocation anyway, and the whole exercise was a waste of time.
\Sliouniaev\
Another advantage is that value objects can be packed into a continuous area in memory, which improves locality of reference and reduces working set (thus improving co-existence of multiple programs in memory). As long a reference to an isolated element inside the array is not passed out, there is no need to allocate a copy on the heap.
\Sliouniaev\
If an object exists solely within a local scope, and is not passed to another method on another object or returned from the local scope, then a JVM is free to do a stack optimization today.
The problem is that the number of cases where a JVM can safely do this are quite low - code has a tendency to pass references to objects outside of their scope or outside of their local compilation unit. When that happens, JVM's opt for safety over a small speed benefit.
\Sliouniaev\
Yep, multiplying matrices of complex numbers is an easy exersise in using The Simple Language. Oh, only two-dimensional arrays are not supported and infix notation which we learned in primary school isn't either.
\Sliouniaev\
Java isn't optimized to be a scientific or mathematics oriented language. Neither is C for that matter (pointer aliasing disallows a number of aggressive operations that a Fortran compiler is allowed to use, for example). You can do such programming in Java with decent performance (but not outstanding), but it's not going to be as convenient as it is in other languages.
The best observation I can make on that is "live with it". Java does some thing s exceptionally well, and provides some extraordinary guarantees to programmers, but it is not all things to all people. I prefer to live with a fairly simple language with concrete guarantees than a be-all-things-to-all-people language like C++ which confuses even grizzled veterans, and provides few guarantees and lots of opportunities for crashes. This may disqualify the language for hard-core numerics coding, but it immeasurably eases the lives of countless developers who have no or infrequent need to multiple matrices (as an example).
In short - you've repeatedly remarked on the performance plusses that can be gained out of languages like C and C++, and completely ignored the negative aspects of these language design choices. In the case of stack-allocated objects, a performance gain can be extracted, but the cost of that gain is IMHO far outweighed by the language complexity it involves, makes JVMs and JITs even more complicated, and raises the likelihood of your program crashing right out from under you.
-Mike -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 12 2003 03:14 EDT
- in response to Valentin Sliouniaev
I disagree, with JIT's this would work rather well. Since you hardcode
> > return true within the overriden method you can get the advantages of
> > virtual method inlining and have NO COST of evaluation and complete
> > removal of the else code!!
> > This means the JIT in this case can EASILY erase a completely redundant if.
>
> IMHO, hardly so if you scan thousands of different characters in a
>single loop... do you have more info about how it works?
I guess you were talking about the map solution while I was talking about
the first solution. With the map solution performance should be similar to
the performance of the switch statement although I never tested it myself.
Years ago I read an article that claimed that using this pattern in C++
with STL maps is faster than a C++ switch statement.
Technically if looking up a String in a HashMap you will run through a hash
algorithem that won't compare strings unless it has to. Generally strings
should be interned for performance.
A set of huge performance advantages with this approach can be gained without
the JIT. You can eliminate elements from the map if you know they aren't
necessary for a particular user in runtime (imagine chaning your switch
statement in runtime to match execution). You can lasily or eagerly create
the map.
The main gain however is dynamic, I allow people to extend my code without
touching it which is very usefull for working in teams and essential for
API's.
> So, I have a form, which allows the user to register a plane. It has two drop
>downs: engine type and plane type:
>
> enum {glider, spring, pedal, prop, turboprop, turbofan, jet, rocket};
> enum {civilian, military, vintage};
You are making my case for me ;)
This data should come from a table in the database... Most of the application
if at all should not be aware of the differences between these gets since
most of the differences are the data such as the mesh that represents them.
> Questions:
> - which part of the code is responsible for converting codes into text?
A select statement, or an Entity EJB or JDO you name it. If you want to you
can even send it by LDAP.
> - which part of the code is responsible for parsing user input into engine
>type and plane type?
I usually send the string values to the EJB tier and work on them there.
Some of my colegues feel that the application context should cash lookup tables.
> - how do I map the two entered values to 24 createXxxxYyyy()?
You don't you have a single method that either takes a string or a number but
this method will use lookup and so will other methods. Its the responsibility
of the database to handle such things.
> - how does a third-party method, e.g. sendEMailToRelevantAuthority(),
> determine if a plane is civilian or military?
PlaneEntityLocal local;
local.isCivilian();
Would work IMO.
> > Java has only pointers and no stack objects ;)
>
> Which is a pity, IMHO. Such thing as value objects (e.g. peers of primitive
>types) would greatly help to improve performance. E.g why can't we allocate a
>Complex or a Point on the stack, along all local ints and doubles? Well perhaps
>it might be possible to optimise it taking immutability in consideration?..
Its not really possible to have stack objects in dynamic languages. Not an
expert on C# but I read that while they have stack objects, the moment you
pass them out of a method they automatically become regular objects....
If this is indeed true then this is just about the stupidest thing I ever
heard, furthermore people won't realise that they are paying the price and
not gaining any benefit.
I never saw the need for a stack object sicne most objects are passed between
elements in the application otherwise I wouldn't make them. -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Robert Devi
- Posted on: April 12 2003 11:14 EDT
- in response to Shai Almog
Its not really possible to have stack objects in dynamic languages. Not an
> expert on C# but I read that while they have stack objects, the moment you
> pass them out of a method they automatically become regular objects....
> If this is indeed true then this is just about the stupidest thing I ever
> heard, furthermore people won't realise that they are paying the price and
> not gaining any benefit.
>
> I never saw the need for a stack object sicne most objects are passed between
> elements in the application otherwise I wouldn't make them.
I remember looking at C# a bit, and from what I remember, stack objects are implemented via structs. Structs are value objects like int and long so they are copied when you assign them. They can have member functions and members, like classes, but carry several restrictions. When you pass them to a member function:
void foo(MyStruct bar);
the member function foo() recieves a copy of the struct, not a reference. However things start to get a bit complicated if you change the definition to any of the following:
void foo(Object bar);
void foo(Ref MyStruct bar);
void foo(Out MyStruct bar);
because in any of these cases the struct is passed as a reference. I have no idea what will happen if foo() decides to hold onto this reference or what happens when you return a struct to a local variable by value. Since the C# runtime is supposed to be as secure, I'd imagine that either the struct is automatically allocated on the heap at the point it's converted into a reference or the C# runtime has some way of detecting that the stack object no longer exists and throws an exception. I personally can't see an efficient way of doing either of these safety features.
You can find out more information here:
http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=120
http://www.dotnetextreme.com/articles/paramtypes.asp
Value objects like structs have some uses and can save a significant amount of memory. If Java had value objects, the enum (under the current implementation) would be implemented as a struct and thus using them in EJBs would not lead to hairy object-identity issues.
However, you get into a lot of hairy issues once you decide that structs can be sometimes used as reference values (e.g. their base class is Object or you pass them into methods by reference). If value objects were ever added to Java, I'd hope they'd do it cleaner than C#. IMO, it was a mistake to have structs derive from Object, and thus have reference semantics in some instances. If C# wanted to give structs reference semantics, they should have done it in a way similar to the way int and Integer are related. With generics, it's easy to define a "Struct<T>" class that can wrap all structs.
Is this feature worth it? I doubt it. I've yet to come across a situation in Java where I had to allocate an enormous number of value objects of the same type. If I were writing such an application (they do exist) in Java, I'd do it via a wrapper class such as this:
class ComplexArray {
double[] m_real ;
double[] m_imaginary ;
ComplexArray(int size) {
m_real = new double[size] ;
m_imaginary = new double[size] ;
}
Complex getNth(int index) {
return Complex(m_real, m_imaginary) ;
}
//...
}
Yes it's a kludge, but it's easy to understand and use, and you don't need to be a language nazi to understand the finer points of value object semantics to use it. Besides, places where you have large numeric arrays like this, you rarely use raw arrays directly and instead user wrapper classes that implement features like sparse arrays or partial incremental calculations. -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Valentin Sliouniaev
- Posted on: April 12 2003 19:41 EDT
- in response to Shai Almog
Hello Shai,
> I guess you were talking about the map solution while
> I was talking about the first solution. With the map
> solution performance should be similar to
Yes, if the value is a string. However a map lookup will always slower than a switch over an integer within a small range (like enum).
> > - which part of the code is responsible for parsing user
> > input into engine type and plane type?
> I usually send the string values to the EJB tier and
Please... It is a stand-alone flight simulator game. :-) Yet I want my huge code to compile properly and work with engine types and plane types as separate types, not strings, not integers...
> > - how do I map the two entered values to 24 createXxxxYyyy()?
> You don't. You have a single method that either takes
> a string or a number but this method will use lookup
> and so will other methods. Its the responsibility
> of the database to handle such things.
I got it. From now on I always use strings for values and map lookups to switch to blocks of code. :-)
Well if the map is totally dynamic and expandable at runtime, it's worth the effort. However if the set of code blocks never changes (e.g. a default one is executed if the lookup returned 'null'), it is very much like a switch to me, only with a lot of syntactic bitterness.
Perhaps Java could allow strings to be used as argument of the switch and would do an internal map lookup. No syntactic somersaults would be required. (Josua?..)
Wait a second, if the set of the strings never changes between compilations, why not map them to sequential integers at compile time (or class load time)and use a superfast integer lookup instead of the hashmap lookup?
How would the compiler know which strings to map? Well, you tell it that this group of strings is a value set for some "type" of values.
How would the user see the strings? Well, just override the .toString() method on the type. How would the program parse the user input? Well, just implement .valueOf() method(s).
Oops, looks like an enum to me. In addition, you get type safety for free, it will be impossible to mistype the enum's value and you could use...
I was going to say '==' instead of .equals(), but alas, in Java it is confusing: one has to know first if the variable holds a primitive type or an object. Well, .equals() anyway, as we also need .toString() and .valueOf(), and, unlike in some other languages, Java doesn't have methods for primitive types.
Anyway, except extreme cases of a programs which modify their own behavior at runtime...
Strings are poor man's enums! :-)
regards,
--VS. -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 13 2003 03:07 EDT
- in response to Valentin Sliouniaev
I guess you were talking about the map solution while
> > I was talking about the first solution. With the map
> > solution performance should be similar to
>
> Yes, if the value is a string. However a map lookup will always slower than a
>switch over an integer within a small range (like enum).
Looking up an Integer object within a HashMap should be practically immidiate
with a decent JIT and cost slightly more than an array lookup in case the
hash function is good.
Better yet, if the number is sequential we don't need a Map you can use an
array lookup like RunnableArray[param].run(). Technically this is what a
HashMap does only it has two levels of indirection which should be very
fast.
> > > - which part of the code is responsible for parsing user
> > > input into engine type and plane type?
>
> > I usually send the string values to the EJB tier and
>
> Please... It is a stand-alone flight simulator game. :-) Yet I want my huge
>code to compile properly and work with engine types and plane types as separate
>types, not strings, not integers...
Why? So you have a single file that an entire application that takes 2 hours
to compile requires? Everytime you make a change a team of over 30 people
will need to sit two hours only to find out you broke their code that relied
in some way on the structure.
Techinically we have a database and an object should be able to persist itself
to some degree. The code using ENUM's is always a HUGE switch statement that
just serves as a huge bottleneck for the application.
Anyway usually I wouldn't use or parse strings... I would try to target my
own needs, lets take for instance the plane type ENUM. Rather than have
an ENUM which the plane class needs to query in every function. Id have
subclasses for each plane. When I wish to create the plane (on loading) I
read the class name of the plane from the DB and do a Class.forName() which
results in a working plane. This allows us to add planes dynamically which
was a requirement we could not implement with our ENUM hardcoded structures.
> > > - how do I map the two entered values to 24 createXxxxYyyy()?
>
> > You don't. You have a single method that either takes
> > a string or a number but this method will use lookup
> > and so will other methods. Its the responsibility
> > of the database to handle such things.
>
> I got it. From now on I always use strings for values and map lookups to
>switch to blocks of code. :-)
When did I say that?
If you need to run specific code according to a specific number/string from
the client database use a Map/Array. If you just need to pass data then you
use strings in the Database. ENUM's are poor mans database constant tables
and every single large application allows you to define dynamically the
constants that you use in the database table. This allows relational integrity
within your database and I will bet that if you are writing a server side
application that you simply map your ENUM's into a database table! This means
that every time the data changes your code breaks!!! Thats just sad.
> Well if the map is totally dynamic and expandable at runtime, it's worth the
>effort. However if the set of code blocks never changes (e.g. a default one is
>executed if the lookup returned 'null'), it is very much like a switch to me,
>only with a lot of syntactic bitterness.
Well I can't technically write switch statements since all the data is in the
database. Within the database I may have a property like civilian (aircraft)
and so I just don't run into the need to use switches. If people invested
just a little amount of time thinking about how to do this correctly ENUM's
would not be needed.
> Perhaps Java could allow strings to be used as argument of the switch and
>would do an internal map lookup. No syntactic somersaults would be required.
>(Josua?..)
NO! That would be hardcoding the strings just as bad as ENUM's.
I think your fixating on some of the things I said, when technically I don't
even think about NOT using ENUM's... I write code that is generic as much as
possible and ENUM's just don't appear. There are hardly any Map lookup's for
Integer/String's within my code since most of the right attributes are stored
in the database.
> Wait a second, if the set of the strings never changes between compilations,
>why not map them to sequential integers at compile time (or class load time)and
>use a superfast integer lookup instead of the hashmap lookup?
#1 There is no such a thing as never changes.
#2 Databases have these, they are called lookup tables and do provide integer
values for the "database enums" which is the right place to put "enum like
functionality" within the user data.
#3 Since string is final the hashCode method can be inlines and string map
lookup is rather fast. While switching over an int is faster it does a different
thing. The map solution provides both parsing and interpretation support which
is considerably faster than the switch alternative. Not all of your data comes
from controlled numeric sources.
> How would the compiler know which strings to map? Well, you tell it that this
>group of strings is a value set for some "type" of values.
>
> How would the user see the strings? Well, just override the .toString() method
>on the type. How would the program parse the user input? Well, just implement
>.valueOf() method(s).
>
> Oops, looks like an enum to me. In addition, you get type safety for free, it
>will be impossible to mistype the enum's value and you could use...
I didn't get any of this, and obviously I never asked for any changes in the
language to get MY code working more effciently or elegantly. You seem to be
stuck in a mindframe that won't let you think outside the box, I suggest you
take a good look at your code and don't think about how to remove ENUM's
think about how it should have been implemented in an object oriented generic
manner.
> I was going to say '==' instead of .equals(), but alas, in Java it is
>confusing: one has to know first if the variable holds a primitive type or an
>object. Well, .equals() anyway, as we also need .toString() and .valueOf(),
>and, unlike in some other languages, Java doesn't have methods for primitive
>types.
Technically Strings can be compared with == after invoking intern() which I
usually do to bring performance up.
> Anyway, except extreme cases of a programs which modify their own behavior at
>runtime...
Why, it doesn't cost neither in performance or code.
> Strings are poor man's enums! :-)
ENUM's are poor mans logic and database replacements. -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Valentin Sliouniaev
- Posted on: April 13 2003 08:32 EDT
- in response to Shai Almog
Shai wrote:
> Why? So you have a single file that an entire
> application that takes 2 hours to compile requires?
> Everytime you make a change a team of over 30 people
> will need to sit two hours only to find out you
> broke their code that relied in some way on the
> structure.
Apparently not if enums are bound at class loading time. Incidentally, alas, I'd still need to recompile everything if my method signature changes. I mean, manually edit and recompile every method I point to with the hash map.
> subclasses for each plane. When I wish to create
> the plane (on loading) I read the class name of
> the plane from the DB and do a Class.forName() which
> results in a working plane. This allows us to add
> planes dynamically which.
If I wanted to add a new type of the engine to my flight simulator game, how many new classes would I need to create? Consider this in the context of a flight simulator game, where the user may create her/his own plane with a combination of a few discrete independent properties like {engine type}, {civilian|military|training|vintage}, {...}, etc. Looks like I do need a database and perhaps a team of code writers.
...which also somehow reminds me of absense of such a good thing as mixin classes that allow adding implementation of standard features to different trees of class hierarchies. Miss it. :-(
> ENUM's are poor mans logic and database replacements.
I guess we are never going to agree. You're talking about EJB and databases, I am about standalone applications running on today's ordinary computers, not expensive workstations. Since Java pretends to be a universal language, it should support some features which will make it faster and writing fast code - more maintainable.
The language may be simple, but doing double somersaults to express a very simple construct doesn't make the use of the language simple. I'd rather use C++ or C#. Or perhaps Smalltalk or LISP or Delphi. Luckily, the .Net platform seems to make it possible. And they wouldn't sue me if I invented yet another language :-).
That would be thinking outside the box: add constructs which help express the solution in a clear way and hide standard implementation patterns in the compiler and the runtime. Conversely, contorting the code inside out is precisely thinking inside the box. :-)
thanks,
--VS. -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 13 2003 15:01 EDT
- in response to Valentin Sliouniaev
Why? So you have a single file that an entire
> > application that takes 2 hours to compile requires?
> > Everytime you make a change a team of over 30 people
> > will need to sit two hours only to find out you
> > broke their code that relied in some way on the
> > structure.
>
> Apparently not if enums are bound at class loading time. Incidentally, alas,
>I'd still need to recompile everything if my method signature changes. I mean,
>manually edit and recompile every method I point to with the hash map.
Yes you will need a rebuild as you do with static final variables.
Thats one of the reasons I advocate making constants private.
My point is that one of the basic concepts on generic OO design is decoupling.
Tight coupling works sometimes for small modules but ENUM's force tight
coupling that won't allow your application to ever scale. This was the exact
problem I'm describing. A small 100,000 line simulator was our initial code
base. In time we turned it into 1,000,000 lines of code but we didn't have the
forsite do dump the ENUM's this made changes impossible.
I don't get people holding on to ENUM's, OTOH people still use goto in C in this
day and age so. What I want is the establishment to treat ENUM's as it does
the goto statement (I smell a PHD thesis ;)
> > subclasses for each plane. When I wish to create
> > the plane (on loading) I read the class name of
> > the plane from the DB and do a Class.forName() which
> > results in a working plane. This allows us to add
> > planes dynamically which.
>
> If I wanted to add a new type of the engine to my flight simulator game, how
>many new classes would I need to create? Consider this in the context of a
>flight simulator game, where the user may create her/his own plane with a
>combination of a few discrete independent properties like {engine type},
>{civilian|military|training|vintage}, {...}, etc. Looks like I do need a
>database and perhaps a team of code writers.
No, you create one class for one problem.
MyPlane extends BasePlane {
public isCivilian() { return(true); }
public isTraining() { return(false); }
}
Or you simply have GenericPlane() that reads this data from the
database.
I specifically said that anything done with an ENUM can be done for the same
amount of code or less, in a generic OO way.
> ...which also somehow reminds me of absense of such a good thing as mixin
>classes that allow adding implementation of standard features to different
>trees of class hierarchies. Miss it. :-(
Are you talking about multiple inheritance?
Try the wonders of debugging virtually inherited classes and you will see some
of what I mean. IS A relationship is by nature singular and should be treated
as such. Implementation inheritance is powerful but limiting and shouldn't be
overused.
> > ENUM's are poor mans logic and database replacements.
>
> I guess we are never going to agree. You're talking about EJB and databases, I
>am about standalone applications running on today's ordinary computers, not
>expensive workstations. Since Java pretends to be a universal language, it
>should support some features which will make it faster and writing fast
>code - more maintainable.
I write that type of code when working with a properties file and when working
on a cell phone (yes I have deployed code on all the Java platforms in real
life projects).
But I guess we won't see eye to eye, one quesion though? Why don't you use C#
or C++ if you miss these features so much? If you do, then why make Java
something its not, C# has already entered the market and there is no benefit
in following later and poorly.
> The language may be simple, but doing double somersaults to express a very
>simple construct doesn't make the use of the language simple. I'd rather
>use C++ or C#. Or perhaps Smalltalk or LISP or Delphi. Luckily, the .Net
>platform seems to make it possible. And they wouldn't sue me if I invented yet
>another language :-).
Ok.
> That would be thinking outside the box: add constructs which help express the
>solution in a clear way and hide standard implementation patterns in the
>compiler and the runtime. Conversely, contorting the code inside out is
>precisely thinking inside the box. :-)
People use ENUM's because that is what college professors teach...
I have yet to see a single person that finishes colege who has a clue about
OO development and design besides the stuff very basics. -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Mike Spille
- Posted on: April 13 2003 16:02 EDT
- in response to Shai Almog
\Almog\
My point is that one of the basic concepts on generic OO design is decoupling.
\Almog\
The purest, most OO-possible design is not always the best solution to a given problem. Sometimes a straightforward use of a simple construct like an enum very simply solves the problem better than a more OO approach. This
Just as 100% pure OO solutions can go terribly wrong - everything over abstracted so that the code is impossible to follow and slower than a dead dog - overusing something like an enum can go terribly wrong as well. Personally, I like the idea of adding enums to Java, because it's easy to do and low in the cost of language complexity. And it doesn't violate any existing Java guarantees.
-Mike -
Is it bad to have good ideas?[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 14 2003 02:34 EDT
- in response to Mike Spille
\Almog\
> My point is that one of the basic concepts on generic OO design is decoupling.
> \Almog\
>
> The purest, most OO-possible design is not always the best solution to a given
>problem. Sometimes a straightforward use of a simple construct like an enum very
>simply solves the problem better than a more OO approach. This
People say that about primitives as objects and about many concepts in the
object oriented world. However they don't say that about the methodologies
and abstractions we use to remove ENUM's. Every single one of the solutions
I use is at least as fast as the ENUM solution (if not faster) and more OO
(dynamic, generic extensible).
> Just as 100% pure OO solutions can go terribly wrong - everything over
>abstracted so that the code is impossible to follow and slower than a dead dog
>- overusing something like an enum can go terribly wrong as well. Personally,
>I like the idea of adding enums to Java, because it's easy to do and low in the
>cost of language complexity. And it doesn't violate any existing Java
>guarantees.
The point is that the object oriented solutions take roughly the same amount of
code but are far better. I don't want an ENUM construct because it will
LEGITIMIZE this construct which is dead wrong.
Unlike asserts which you don't have to use, ENUM's will be required by API's
and that would mean 2 things:
1. API's will be implemented badly
2. I will have to use them
Regarding the point of ENUM's being easy....
I like to say that every ENUM has a switch... The ENUM methodology requires
hardcoding, breaking of encapsulation and centering logic. These are all really
bad things, the worse thing though, is that we teach them to beginners!
101 classes allways teach ENUM's, which pretty much fixates this horrible coding
style in young minds. So what may seem like a harmless simple solution at first
is in fact a huge problem when I need to "reeducate" college graduates on how
to "really" program.
The annoying part is that the solutions of using ENUM's are only simpler when
writing test cases and such. With real world data you need to turn string data
into enums back and forth for every typical transaction which is both an
overhead in performance and in logic (its practically impossible to keep table
data and ENUM's in sync). So we are teaching people a simple way to fail when
they get to the real world? Java is not a teaching tool or a beginner language
it is a professional (and the best at that) clean language, and should remain
clean. -
hardcoded still[ Go to top ]
- Posted by: thoff thoff
- Posted on: April 14 2003 09:50 EDT
- in response to Shai Almog
class Aircraft {
> public boolean isF15();
> private void doStuff() {
> if(isF15()) {
....
The problem with this approach is you can never do anything
generically because you have to hard code the name of what
your are interested in. How would i take input from a user
to ask if an aircraft was a specific type? They would type
F15 and the in the program we would do what? We would provide
a picklist and then how do we map that back to the correct isXXX
test? -
hardcoded still[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 14 2003 11:09 EDT
- in response to thoff thoff
class Aircraft {
> > public boolean isF15();
>
> > private void doStuff() {
> > if(isF15()) {
> ....
>
> The problem with this approach is you can never do anything
> generically because you have to hard code the name of what
> your are interested in. How would i take input from a user
> to ask if an aircraft was a specific type? They would type
> F15 and the in the program we would do what? We would provide
> a picklist and then how do we map that back to the correct isXXX
> test?
Yes, not a good example. Normally you would write something like
isFighter(), getWeight(), getEnvelope() etc... and then implement
them in the class F15Jet. That would be rather generic and each
method would map to a feature of the application allowing us to add
jets easily. -
hardcoded still[ Go to top ]
- Posted by: thoff thoff
- Posted on: April 14 2003 12:33 EDT
- in response to Shai Almog
Yes, not a good example. Normally you would write something like
> isFighter(), getWeight(), getEnvelope() etc... and then implement
> them in the class F15Jet. That would be rather generic and each
> method would map to a feature of the application allowing us to add
> jets easily.
Even that's not very OOish. Why do you need type related questions
like isFighter? "Is" methods are often hidden little switch statements. Can
you make a method that would do whatever you need to do without
switching on isFighter? -
hardcoded still[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 15 2003 01:57 EDT
- in response to thoff thoff
Yes, not a good example. Normally you would write something like
> > isFighter(), getWeight(), getEnvelope() etc... and then implement
> > them in the class F15Jet. That would be rather generic and each
> > method would map to a feature of the application allowing us to add
> > jets easily.
>
> Even that's not very OOish. Why do you need type related questions
> like isFighter? "Is" methods are often hidden little switch statements. Can
> you make a method that would do whatever you need to do without
> switching on isFighter?
Its not switching when its a single generic if.
Thats by the book OO design.
If I have a requirement for fighter jets I can simply ask whether
the plane is a fighter jet and act accordingly rather than have
a huge if on all the ENUM types.
What would you consider as OO? -
hardcoded still[ Go to top ]
- Posted by: Shai Almog
- Posted on: April 15 2003 03:35 EDT
- in response to Shai Almog
Yes, not a good example. Normally you would write something like
> > > isFighter(), getWeight(), getEnvelope() etc... and then implement
> > > them in the class F15Jet. That would be rather generic and each
> > > method would map to a feature of the application allowing us to add
> > > jets easily.
> >
> > Even that's not very OOish. Why do you need type related questions
> > like isFighter? "Is" methods are often hidden little switch statements. Can
> > you make a method that would do whatever you need to do without
> > switching on isFighter?
BTW the properties of isFighter() etc... can be loaded from the database
this all depends on the implementation. If we need to write a class for
each plane then it might be best to just code its properties since the
code needs to know them anyway. If we are building a more generic simulator
(this is not really possible if you reach a high level of details since planes
are very different from each other) then might as well code these elements.
Loading ENUM's from the database is a switch to load and switch to save.
Furthermore, even hardcoded return(true) can later be refactored to loaded
data without modifying the API. -
Are enums limited?[ Go to top ]
- Posted by: Piotr Zakrzewski
- Posted on: April 14 2003 06:47 EDT
- in response to Shai Almog
Could anyone tell me whether enums are in any way "limited classes" in JSR-201? If they're only some syntax-sugar extension to normal classes, I'll not agree that they're not OO. I am really often using a "type-safe enum pattern", and these enums falls mainly to two categories:
- a mix of Singleton and Flyweight patterns (good example would be Boolean.FALSE and Boolean.TRUE),
- state-like values of database columns (I would rather like to guard values by type-safety, than use plain ints).
I see nothing wrong in using enums for this, and in fact using them is even more OO (I hate ints).
Best regards,
M.. -
Text of the Tech Talk ?[ Go to top ]
- Posted by: Hemant Gohil
- Posted on: April 10 2003 12:48 EDT
- in response to Nitin Bharti
Are you plaaning to post TEXT of the Tech Talk ?
Thanks -
Thumbs Up[ Go to top ]
- Posted by: Dmitriy Setrakyan
- Posted on: April 10 2003 13:43 EDT
- in response to Nitin Bharti
Even though Java is much superior to .NET, I really do enjoy seeing Java finally taking steps in adding essential language features that have been present in other languages including C#, such as enums, metadata, automatic boxing, "for each" loop iteration, etc
However C# continues to suffer from many deficiencies, like ugly events support, lack of inner classes, lack of checked exceptions (which is a total disaster ), immature APIs
While working in a company that is evenly split between Java and .NET development, differences and deficiencies on both sides become very evident. New JDK 1.5 is definitely a welcomed development on Java side.
Dmitriy Setrakyan
Fitech Labs, Inc - xNova, Service Oriented Architecture for Java and .NET -
Tech Talk with Joshua Bloch on New Java Language Constructs[ Go to top ]
- Posted by: Francis Amanfo
- Posted on: April 10 2003 14:06 EDT
- in response to Nitin Bharti
This would be a great enhancement to the Java platform therefore I think this deserves to be called Java 2.0 instead of 1.5! -
Java version numbers...[ Go to top ]
- Posted by: null
- Posted on: April 10 2003 14:56 EDT
- in response to Francis Amanfo
There is a problem with naming it Java 2.0, which they should have forseen when they started the marketing campaign to call Java 1.2 "Java 2". Java 2.0 sounds so retro. Maybe when they get to version 2.0 they will market it as "Java 3"... and so on? Or should they call it "Java 3" starting at 1.5? If so, why not just jump to the 3.0 version number, as other companies have done? -
Java version naming[ Go to top ]
- Posted by: Scott Hodson
- Posted on: April 10 2003 17:20 EDT
- in response to null
Maybe they can call it "Java 2004" :) -
Removal of deprecated members?[ Go to top ]
- Posted by: Brett Hovenkotter
- Posted on: April 10 2003 15:47 EDT
- in response to Nitin Bharti
I've heard a rumor that Java 1.5 would be the first version to actually remove deprecated members, can anyone confirm? It would be nice to see some of the old ugliness go. -
Battle test Java (with C# :-)[ Go to top ]
- Posted by: Valentin Sliouniaev
- Posted on: April 10 2003 20:35 EDT
- in response to Nitin Bharti
I like this bit:
"There are many good ideas ... which are great and we're glad that people are doing them, but they're research and once they're battle tested for 10 years, well maybe they'll have a place in a production language."
How are we going to battle test them for 10 years if the only language Java Universe supports is... Java?
(It seems that presense of C# speeds that up a little bit, anyway. :-)
regards,
--VS. -
battle testing[ Go to top ]
- Posted by: jon harper
- Posted on: April 11 2003 01:54 EDT
- in response to Valentin Sliouniaev
"How are we going to battle test them for 10 years if the only language Java Universe supports is... Java? "
Ad hoc implementations of certain language constructs would provide a means for battle testing new ideas. For instance aspectj provides a way for the concept of AOP to be tested in the industry. Once the run-around implementations prove their worthiness, the concept can be incorporated into the language more effiently
-JH -
battle testing[ Go to top ]
- Posted by: Mileta Cekovic
- Posted on: April 11 2003 05:03 EDT
- in response to jon harper
While I find AOP very usefull concept in improving developer productivity, readibilty and maintainability of souce code, I found AspectJ sintax strange and a bit over-complicated. It is simply not in Java style.
Mileta -
Removing features[ Go to top ]
- Posted by: Brian Matzon
- Posted on: April 11 2003 02:59 EDT
- in response to Nitin Bharti
There are things I would change. For example, I think the Switch
>statement should have been more structured. I don't think it makes
>sense to have a fall through from the Case as was the case in
>the C programming language.
I use this construct *so* often!
The only way to make this possible without fallthroughs, is to use the gogto keyword, like in C#/VB .NET - we really want this?? -
Removing features[ Go to top ]
- Posted by: Mileta Cekovic
- Posted on: April 11 2003 04:43 EDT
- in response to Brian Matzon
There are things I would change. For example, I think the Switch
>>statement should have been more structured. I don't think it makes
>>sense to have a fall through from the Case as was the case in
>>the C programming language.
>I use this construct *so* often!
>The only way to make this possible without fallthroughs, is to use the gogto >keyword, like in C#/VB .NET - we really want this??
Heve you seen the Pascal case statement ? It is clean and structured. Something Java should have instead of this dirty C-like switch statement. I don't say C switch statement is bad for C, only that it is bad for Java, :)
Regards,
Mileta -
Removing features[ Go to top ]
- Posted by: Valentin Sliouniaev
- Posted on: April 11 2003 09:01 EDT
- in response to Mileta Cekovic
Alas, removing the last cool bit will make it _even more_ like Pascal (where is it now?..). There won't be anything to confuse people with any more, like this snippet of real Java below:
static void bar() {
for (int i=0; i<5; ++i) {
try {
if (i%2==0) continue;
System.out.println("foo " + i);
} finally {
System.err.println("bar " + i);
}
}
}
:-),
--VS.
PS. I saw it printed all the 'foo's before all the 'bar's. Why?... -
Removing features[ Go to top ]
- Posted by: David Hamilton
- Posted on: April 11 2003 10:05 EDT
- in response to Valentin Sliouniaev
Nice one Valentin - you almost had me going there...
Of course, if you change the 'System.err' to 'System.out' you'll see what you'd expect :-)
/david -
Removing features[ Go to top ]
- Posted by: Maris Orbidans
- Posted on: April 11 2003 13:25 EDT
- in response to Valentin Sliouniaev
what the h*** is "foo" ?
I naver understood that. -
Removing features[ Go to top ]
- Posted by: bob farmer
- Posted on: April 11 2003 14:32 EDT
- in response to Maris Orbidans
"what the h*** is "foo" ?
I naver understood that. "
It's part of the J2EE spec and everybody who implements it needs to get licensed 8~) -
Removing features[ Go to top ]
- Posted by: Valentin Sliouniaev
- Posted on: April 12 2003 20:17 EDT
- in response to bob farmer
-
Foo[ Go to top ]
- Posted by: Darius Cooper
- Posted on: July 25 2003 10:43 EDT
- in response to bob farmer
"what the h*** is "foo" ?
It's a type of widget. -
foo[ Go to top ]
- Posted by: thoff thoff
- Posted on: April 14 2003 09:50 EDT
- in response to Maris Orbidans
Foo comes from fubar which stands for fucked up beyond
all recognition. A military term. For some reason people
like to spell it foo instead of fu. -
foo[ Go to top ]
- Posted by: James Hollow
- Posted on: May 12 2003 11:49 EDT
- in response to thoff thoff
Foo Bar means nothing, thats the point if it. -
What 'foo' is....[ Go to top ]
- Posted by: James Shipley
- Posted on: May 07 2004 11:33 EDT
- in response to Maris Orbidans
-
Concurrency Libraries[ Go to top ]
- Posted by: David Hamilton
- Posted on: April 11 2003 10:52 EDT
- in response to Nitin Bharti
Good to see that they are still intending to get the concurrency libraries into 1.5. To me that is probably the single most important change...
...however a revision to the JLS to allow double checked locking to be guaranteed to work would be equally welcome.
/david -
Concurrency Libraries[ Go to top ]
- Posted by: Massimo Luise
- Posted on: April 14 2003 03:35 EDT
- in response to David Hamilton
...however a revision to the JLS to allow double checked locking to be guaranteed to work would be equally welcome.
why not a construct like this
synchronized( object, boolean expression ) {
...
}
where the block is executed synchronized after having evaluated true the expression and taken the lock atomically with the evaluation.
Max -
How about supporting Hot Deployment of classes[ Go to top ]
- Posted by: sean decor
- Posted on: April 11 2003 13:29 EDT
- in response to Nitin Bharti
it sucks a lot to re start the app server all the time .... -
New features influence changes in APIs[ Go to top ]
- Posted by: Nebojsa Vasiljevic
- Posted on: April 13 2003 07:03 EDT
- in response to Nitin Bharti
New Java language features will change good practice in API design. Most of existing APIs should be changed to fulfill new good practice.
I can see new Collection API, but what other APIs in JDK 1.5 (like Swing, JDBC ...) will be upgraded to use new features?
What backward compatibility problems will this produce and what compromises the solutions will introduce? I expect many dual APIs or dual programming styles for same APIs.
What Collection API should learn Java beginner?
Unfortunately, he should learn both new and old.
I like new features very match and am ready to adopt JDK 1.5 as soon as possible, but I also see a lot of problems.
Nebojsa -
Enums will help debugging[ Go to top ]
- Posted by: Vilya Harvey
- Posted on: April 13 2003 18:42 EDT
- in response to Nitin Bharti
I think one of the nice benefits of enums is that debuggers will be able to determine the symbolic code for a value that you are trying to view, rather than just having to show an integer value (for example). This will be quite handy in some situations.