Stack OverflowWhat are the things Java got wrong?
[+87] [44] Alon Aizenberg
[2009-01-19 15:06:33]
[ java ]

I read a lot of blogs and see people all the time talking about bad things in the java programming language; a lot of them are about annotations and generics that were added to the language in 1.5 release. What are the things in the language or the API that you don't like or would design differently?

(12) I don't think that this is "subjective and argumentative". It's a valid critique. With the benefit of hindsight, some things might have been done better in Java. Identifying areas for improvement in future languages is worthwhile. Re-open please. - Dan Dyer
(3) Will never understand why questions like this are closed. Make them community wiki sure, but close? - Binary Worrier
There is not a real answer for this question. It not like "Why am I getting NPE here: String s = null; s.toString()" See the faq to see what kind of questions are SO for. - OscarRyz
@Oscar, in that case we should close every question tagged "subjective". - Dan Dyer
Thx, Allain, bdukes, Oscar and Bombe. Right choice. - Ludwig Wensauer
@Dan, I agree. But since considering something as subjective, is, well subjective, we need vote in group for that. That's what just happened here. - OscarRyz
(2) I'm not arguing against democracy, I'm just a bit confused that this, a question about a programming language, is deemed unacceptable but "If you weren’t a programmer what would you be doing?" (a question that is specifically about not programming) is still open. - Dan Dyer
I think the question could be edited to remove the argumentativeness. - Tom Hawtin - tackline
@Dan: Well yeah. The same as "Favorite Cartoon", "Jon Skeet facts", and some others that are not only open, but they're the among the hottest in here. Search for "Why my question got down voted/closed etc" It has been widely discussed. Is an strange phenomena :) - OscarRyz
But hey, as I'm writing this question needs only one vote to reopen. :) - OscarRyz
My vote's there, but still requires one more. - Lawrence Dol
This should be community wiki - Malfist
this is indeed a nice question, and I'd even say it doesn't need Wiki - Robert Gould
I think it got all wrong. - Hai
@Azafe: oh come on now! No programming language is perfect, but you're just being hyperbolic and non-contributive. - Tom
[+73] [2009-01-19 15:21:26] dalle
  • Checked exceptions.
  • Every object Is a monitor.
  • Primitives are not objects.
  • Lack of properties.
  • The way generics are implemented.

(2) +1 especially for checked exceptions. They could have worked as a hack to get around the inconvenience of returning various types of structured values from functions, but the standard class library uses them for all kinds of annoying and inappropriate purposes. Foul! - bobince
(35) Checked exceptions are fine when used correctly. - Dan Dyer
(11) Except not all exceptions are checked. NullReferenceException, anyone? The jury is still out on whether checked exceptions provide real value, given the ammount of exception-translation work it requires to use correctly. - Aaron
I believe that the argument for checked versus unchecked is that checked exceptions represent something that the program should be able to correct, while unchecked aren't. Of course, there are a lot of exceptions (sorry) to that rule, particularly in javax.xml. - kdgregory
(1) @dalle - it's a nice list, but would you care to provide justification for any of them? - kdgregory
(1) @kdgregory They're generally right. Look around some answers here for details. I can live without properties though, they just encourage the property pattern which, while not ALWAYS terrible, tends to break encapsulation pretty severely. - Bill K
@BillK - and for each of them you can find arguments on the other side. Personally, I'd like to hear a good justification of why primitives are bad; heck, any justification other than "everything should be an object" or "I have to box to use a Collection" would be nice - kdgregory
(4) checked exceptions are great since you need to think about what should be done. The ability to wrap in a runtimeexception can make any checked exception unchecked! - Thorbjørn Ravn Andersen
And the way arrays are not (a) really objects, and (b) not easily resized. - Lawrence Dol
GOD I had java generics. I feel like they are stapled onto Java - Simucal
(14) arrays most certainly ARE really objects. They have a constructor, fields, methods, everything. They get some syntactic sugar and special JVM treatment, that's all. And OF COURSE they're not resizable - that's what ArrayList is for. - Michael Borgwardt
(3) Checked exceptions are great. Problematic in Java are the runtime-exceptions (the not checked exceptions). - Mnementh
(3) I like checked exceptions too. They can be misused but at least they are explicit. - Mr. Shiny and New 安宇
Quote from Satya Komatineni's Blog: "Interfaces and checked exceptions are like butter and sand: they don't mix well" - dalle
The fact primitives are not object is a necessity for performance and interoperability.<BR> The lack of properties is annoying. - Danny Varod
(15) Checked exceptions are horrible. What a great way to cause simple changes to create a cascade of modifications to other classes, and to add a lot of worthless code. Every time I catch an exception only to throw it again (or a different one, or to log it and toss it out), I feel sad. - TM.
@Danny: Not quite a NECESSITY. It's a quick and fast route to get performance and interoperability. But not the only (and not certainly the best) way. - R. Martinho Fernandes
I like the fact they primitives are not objects and that it does not have properties. - Johannes Schaub - litb
Primitives are by definition not objects! They're primitive for performance reasons. The only place this ever runs into problems for me is when you can't use primitives in a place where space/time performance reasons are important. (e.g. ArrayList<int> not allowed but would have been nice) - Jason S
(1) I hate using get... and set... methods. I don't know why, particularly, but, there you go! - Lucas Jones
(1) I disagree with everything above. - GreenieMeanie
(1) @GreenieMeanie: Thoughtful and well put chokes on sarcasm - Ed S.
(3) -1 for properties. Nobody has been able to tell me what's wrong with using public attributes instead ( if what they want to avoid is not to type get/set ) The most common answer is "because you could probably add logic to the property ( hence making it a method ) - OscarRyz
(1) @simucal, that's because they WERE stapled onto Java, in like Java 5... - Brian Postow
About primitives. They don't have to be implemented as objects under the hood, but it would be nice if they could be used like objects in the source. Ruby does this well 1.upto(10) for example. With auto-boxing, the worst things about using primitives have been fixed. - KitsuneYMG
@Oscar: The most common answer is precisely the right one. In Python for example, you may want to define a public variable. If later you decide it should have some code in the getter and/or setter, you can make it into a property without changing the external interface. You could always use getter and setter methods for everything, but properties are cleaner. - Javier Badia
@Aaaron, I don't find I need any exception translation work to use checked exception correctly and see checked exceptions as a strength of Java. However, that may be because I have been programming in Java for 12 years and anything which takes years to use correctly isn't great. ;) - Peter Lawrey
[+64] [2009-01-19 15:14:43] MiniQuark

I really don't like the manipulation of dates in Java (java.util.Date, java.sql.Timestamp, java.sql.Date, java.util.Calendar).

I agree. I found a link today about it, I paste it here:… The fix is coming in Java 7 ( hopefully ) - OscarRyz
Fanstastic. They deprecate the Date functions, replace them with the Calendar. Now they are looking to fix that replacement. Third time's a charm? - daub815
Calendar was a halfbaked package inherited from Taglient. I believe Sun learned quite a bit from that. - Thorbjørn Ravn Andersen
Java dates suck. Calendar sucks too. At my place of work we wrote our own wrapper to simplify the usage, but it still sucks. I feel that Java's date system is the worst of any language I've used. - TM.
All the Java date/time APIs are complete trainwrecks. I really don't understand how they could create something that bad. Hire a 3rd year university co-op and they'd do a better job. - Matt Olenik
(8) JodaTime anyone? It's not perfect, but pretty damned close compared to the Java Date / Calendar api! - Kimble
(1) Absolutely. The calendar class is based on the idea of one of those flipping desktop calendars, and it's wrong, wrong, wrong. It was done in the early days of OO programming. Timezones are a continuous nightmare. JDBC in particular needs a way to pull back a date as a Calendar object. Oh - and it's the wrong word, too. - paulmurray
[+49] [2009-01-19 15:22:09] Jason S


(5) As opposed to never shipped because were still trying to get generics right when the project was cancelled? - Tom Hawtin - tackline
(4) Java's generics piss me the hell off. - Daddy Warbox
C#'s generics are also an afterthought really. They only appeared in what version 3? - Robert Gould
(11) Version 2.0 to be exact. But .NET generics are properly implemented at runtime. Unlike Java generics where Sun was too scared, under vendor pressure, to change the IL to support generics. So you end up with a half assed implementation that has things like "type erasure". - Strelok
2.0 feels almost like a complete rewrite of 1.1 anyway - annakata
(1) The .NET generics work great, except that it caused all code that used non-generics to be "out-of-date", and then when changed to generics caused all the code that uses it to not-compile... At least in Java, with all the problems erasure gives, libraries are still backward compatible... And they give themselves the option to implement it differently later on, when enough people leave JDK 1.4. - Aviad Ben Dov
[+31] [2009-02-03 08:48:51] FA.

Arrays are covariant which shouldn't be.

See: Wikipedia Article [1]


(2) Why is this so highly ranked? Yes covariance of arrays has caused me problems... Once. In 11 years of Java coding. - finnw
(2) This should be higher ranked in my opinion - BlueRaja - Danny Pflughoeft
@finnw: Because it's such a glaring blunder, and it ruins Java's touted type safety. - Mechanical snail
[+29] [2009-01-19 15:11:52] MiniQuark

I think the Java language is overall well designed. I just think it's way too verbose.

(5) The verbosity and rigidity is what make it maintainable as it is READABLE! You are encouraged to be verbose by the example of the runtime library. - Thorbjørn Ravn Andersen
I don't like the huge long lines either, but I agree with Thorbjorn, it often does aid readability. - TM.
(2) VB is a verbose language also. That doesn't make it any better than, a less verbose one. What's wrong with ":" instead of "extends", it's perfectly readable, when you see "class Derived: Base", to think "class Derived extends Base". conciseness.equals(readability) or conciseness == readability ? - Pop Catalin
(30) The important thing is clarity. THEN comes conciseness. C++ = concise & unclear. Java = verbose & clear. Python = concise & clear. ;-) - MiniQuark
(2) C++ is not what I'd call concise. (C++ is naturally obfuscated) I can't say I saw a C++ program that was concise, actually C++ is notorious for the length of it's programs compared to other languages. - Pop Catalin
You're right. I was thinking about expressions like f(a++) which are very short but can actually do a lot a things under the hood, such as calling a copy constructor, call a cast operator, etc. But "obfuscated" is a better word for what that is! - MiniQuark
I think this is mostly a moot point: when reading code, readability is of paramount importance, as others said, and when writing code (as a 'serious' programmer, anyway) you naturally use a good IDE, which autocompletes and fills in everything mundane for you. - Jonik
(1) How can you say Python is clear? I've seen the most awkward expressions in Python... - Aviad Ben Dov
(9) Java: The OOness of C++ with the verboseness of COBOL. - Slapout
(2) @Pop Catalin : what is wrong with ":" instead of "extends" is that extends really means what's happening. If I'm a beginner and I see ":", I can't really know what it means - Valentin Rocher
@Bishiboosh " If I'm a beginner and I see ":", I can't really know what it means". If you're "true" a beginner then the chances are you don't know what extends means ... but once you know what : after class name means (which is one of the first things you learn), dot syntax helps create more readable code (because identifiers are more visible have higher text reading weight). Of course the trick is to not over do it. - Pop Catalin
@MiniQuark, +1: When it comes to terse, KDB is one of the most extreme. (!R)@&{&/x!/:2_!x}'!R gives you all the prime numbers between 1 and R. How? Don't ask me. ;) - Peter Lawrey
@MiniQuark APL wins the terseness contest by 3 symbols, and here's an explanation: - Jona Christopher Sahnwaldt
@Pop Catalin It has nothing to do with beginners in my opinion. The fact that ":" doesn't mean anything to human mind and "extends" does is the point. The less mental translation one has to do, the clearer the language. I could have written this comment without vowels, it would have been less verbose that way, you would have understood it just the same, but it would be a pain to read, yet it was meant to be read. - veggen
As a software engineer you need not to feel 'confused' by the difference between natural language and your programming language of the moment. Instead, you need to learn to appreciate those very differences. For example, ':' has an advantage over 'extend': it is faster to type AND to read. - Gigi
[+29] [2009-01-19 15:23:18] MiniQuark

Ever since I have learned python, I just find that Java lacks the possibility of returning multiple values easily:

#In python:
name, age = john.summary()

//In Java:
Object[] summary = john.summary();
String name = (String) summary[0];
int age = ((Integer) summary[1]).intValue(); #primitive types require boxing

Edit: as mmyers pointed out, the following is legal as of Java 5:

int age = (Integer) summary[1];

This particular issue is currently being discussed here: - Dan Dyer
(13) Something that bothered me at first, but I've since decided that it's a good thing. Forces one to spend the extra time to encapsulate complex returns. - Brian Knoblauch
(3) The problem being that because Java doesn't support value typed structures or by-reference arguments, returning multiple values means a heap allocation on every call. Garbage collection is pretty good, but it's still a waste to do that. - U62
Agree with @Brian (and virtually all arguments are by reference/stack, @RHM) - Bill K
(1) Agree with Brian. - Lawrence Dol
I don't like the Java here. Way too hard to read compared to the Python. - Nosredna
I should point out that the intValue call is not actually necessary. "int age = (Integer) summary[1];" is perfectly legal as of Java 5. - Michael Myers
That happens when you try to use a Python idiom (I know it's used elsewhere as well) that's not "native" to Java: it won't look nice. - Joachim Sauer
@mmyers: Worthy to note that behind the scenes, it will call intValue(). - Aviad Ben Dov
[+24] [2009-01-19 15:11:42] Joao da Silva

On the java platform: AWT, and the XML APIs (it's amazing what you have to do just to parse a String into a DOM tree)

On the language: add type inference and tuples, generics without erasure, make 'volatile', 'strictfp' and 'transient' annotations

(1) the XML api is such a load of horse hooey! - nes1983
(1) If you've got to deal with hooey, wouldn't you want great (long) tools to deal with it? - Tom Hawtin - tackline
(3) volatile and strictfp change the semantics, so aren't really suitable to be annotations. - Tom Hawtin - tackline
+1 for XML APIs. The whole XML stack in Java is a mess, especially the lower parts of stack. - Domchi
+1 for AWT and XML APIs. Many things get a lot easier when using wholly separate XML tools (e.g. dom4j). - Jonik
Quite frankly, I have yet to see any language do XML really well. It's not surprising since it's quite complicated compared to a lot of other markup languages (such as JSON) IMO. - Tom
Gotta love this criticism of the XML APIs by Joshua Bloch: :) - Jonik
Make native an annotation too. I also prefer JNA's access of native functions to JNI - KitsuneYMG
[+22] [2009-01-19 15:09:46] fbonnet

Primitive types (ints etc.) are not objects like in Smalltalk, forcing the programmer to use boxing classes such as Integer.

Smalltalk integers are real objects. In order to avoid overhead, they are not implemented as "boxed" primitives, like Java does, but instead as "immediate" objects: the object's value is stored within the object "pointer" (the same is true with individual characters) To do so, it uses the pointers' low bits, which are always zero for regular objects (since structures are usually word-aligned), as "tags" to differentiate immediate objects with the former. For example, if a pointer's bit 0 is set, it designates a SmallInteger object: its integer value is stored in the remaining 31 bits. Larger integers use regular objects with infinite precision (AKA bigint).

Java 5's autoboxing is the worst of all solutions, because it hides the overhead behind syntactic sugar: the programmer is unaware of the fact that objects are created behind his back although he's using primitives. Not only that, but several Integer objects could be created for the same int value. Whereas in Smalltalk, the value IS the objects. This also allows the compiler to generate optimal code, in a way that can't be done with boxed objects. Smalltalk proves that primitive types can be objects AND be implemented efficiently.

This is one of the reasons why Java cannot be considered a high level language (not that this can be a problem or drawback in any way, there is ample room for system level programming languages).

Interesting, that's something that I like about Java! :-) - Brian Knoblauch
(8) Primitives also don't have the memory / computational overheads that Objects do. If anything, primitives are a feature. - Richard Walton
Also, since Java 5.0 there's autoboxing - Joao da Silva
@Richie_W: first-class primitive objects don't have to be heavy. See Smalltalk or Lisp for examples, where they are implemented as immediate values (for example, storing the integer value within the pointer). This is the reason why Java cannot be considered high level. - fbonnet
@João da Silva : sure but this is just sugar - the JVM still makes the distinction. So autoboxing adds overhead behind the programmer's back. - fbonnet
fbonnet: how could there not be overhead? Do you think integers in Smalltalk (or any other OO language that can reat an integer as an object) adds no overhead? How would they do that? - j_random_hacker
(1) @j_random_hacker: see my edited answer for more info about Smalltalk's immediate objects. - fbonnet
(2) I won't mark you down because you definitely thought out your answer, but everything you just said they got wrong is things I believe they got right. - Except leaving out auto-boxing, which they later fixed. :o - 280Z28
what evidence do you have that the auto-boxing brings overhead ? Can you objectively quantify this overhead and give example of where it is detrimental to the program when compared to using objects all the way ? Other than the few more keystrokes how different is it when using Integer objects in Java directly vs smalltalk objects primitives ? - Newtopian
I have never seen autoboxing take a significant percentage of CPU time in code I've profiled. - finnw
@fbonnet: Your edit was helpful so I've dropped my -1. But I'm with 280Z28, I still feel that the autoboxing-with-full-size-primitive-datatypes approach is cleaner, and I would expect faster (since with Smalltalk's "hybrid" representation, every arithmetic operation must need a pre-right-shift and post-left-shift, no?) - j_random_hacker
[+22] [2009-01-26 11:09:52] Lemmy

All References are nullable

All references are nullable, which causes a lot of NullReferenceExceptions. I think something like "Option" (Scala) is better suited for those rare cases where an object reference actually should be able to be "Nothing". Of course that would have required Generics and some Pattern Matching right from Version 1.

I'm currently trying to compare the pros/cons of Code Contracts vs. Spec# as a way to correct this issue in C#. - 280Z28
Shouldn't that be "References are nullable"? Since an Object can't be null. - Joachim Sauer
true true...fixed it - Lemmy
I would agree that the default behaviour of a reference should be that it can't be null. One type which is often assumed not to be null but can be is enums. You can have a switch(myEnum) { default: } but have it fail with an NPE. - Peter Lawrey
(3) @PeterLawrey: When an array of references is created, what should it initially contain? - supercat
[+21] [2009-01-24 01:32:48] Germán

The test-unfriendly servlet API... you need a framework to be able to mock a bloody Request!

[+19] [2009-01-23 23:41:58] j_random_hacker

No destructors, therefore no possibility of RAII [1].

Most objects are memory-only, which Java's GC handles just fine. But whenever you have a class that allocates non-memory resources (e.g. DB handles), you need to remember to clean it up in a finally block every time you create an instance -- so you need finally blocks everywhere containing the same cleanup code, and if you forget one place, bang, resource leak as soon as an exception is thrown in that scope.

This is one of the (few?) things C++ got right -- you write the cleanup code just once in a destructor, and the language guarantees that it will always be called when an instance of that class goes out of scope, even in the event of an exception. I realise that Java is GC-collected, but RAII and GC are not mutually exclusive -- there just needs to be a way to specify deterministic destruction at scope exit for a particular class or instance, and to provide a destructor. Really, you would not believe how much this simplifies resource management.

It's been 5 years since I touched Java, maybe this has changed?


So Java doesn't have the IDisposable / Using pattern that C# does? - FlySwat
(5) Weak References can do the exact same thing as destructors, but in a much more controlled way. There is a collection with the explicit duty of calling destructors as an object is being GC'd--this stuff has been in there YEARS now and I still hear "no destructors" - Bill K
Bill K: Could you say what collection that is? I googled for "Java RAII", "Java deterministic destruction" and "Java Dispose pattern" and couldn't find anything (except people complaining that Java doesn't have it...) - j_random_hacker
(5) @Bill K: There are no deterministic destructors in the C++ style. Finalizers in Java/C# shouldn't be used in the same way that they are in C++ - they're more a "last line of defence" than "the normal way of cleaning up." - Jon Skeet
@jon Skeet Yes, that's why I suggested references. @j_random Look at the reference queue and weak/phantom references (Also look at WeakHashMap for smart caches). Here is a whitepaper: - Bill K
(2) @Bill K: Thanks for the link. Useful classes, but they just prevent unnecessary elongation of an object's lifetime, they don't guarantee finalization. I quote: "Therefore, the bottom line is that you can never guarantee that an available object will ever be collected by the garbage collector." - j_random_hacker
(6) RAII is incredibly useful and Java cannot support it. Using finally is not a scalable solution and it must be done explicitly in the implementation which increases the risk of programmer error. - Bernard
[+16] [2009-01-19 15:32:00] David Thornley

Keeping too much C syntax that was known to be problematic. The switch statement should have been redone for Java. Operator precedence is at least a more complicated problem; while Java could do better than C there was some advantage in keeping it.

One goal for C++ was to be at least a better C, and so Stroustrup had an excuse for keeping bad C decisions. Gosling et al. didn't.

Edit: Also octal literals (thanks, Dan Dyer, for pointing that out). Those are very useful things for writing OS internals and bit-grovelling code, which are applications Java isn't usually used for.

(4) I agree. Fall-through in switch statements is an invitation to write buggy code. Also, do we really need Octal literals? - Dan Dyer
I could go for a re-write of switch. I definitely would NOT throw it out like others would. It has a place, just perhaps not as frequently as some like to use it. - Brian Knoblauch
A switch statement is useful, and making one that's better than the C version that Java uses is not hard at all. Octal literals are another thing (thanks, Dan) that are better suited for C than Java; I'd just get rid of those. - David Thornley
(3) C# allows switch on strings and doesn't fallthrough... - FlySwat
(5) One reason for keeping C syntax was so that developers could easily switch from C/C++ to Java. I think that's a pretty good excuse, because without programmers, a language dies. - Mongoose
C#'s switch is still broken. It can't do ranges and you have to put in break statements. They should have used VB's Select Case as a model. - Jonathan Allen
You don't need break statements Jonathan. - FlySwat
I think you do. Either return, throw or break. - R. Martinho Fernandes
Yes, you do need break statements. - Ed S.
I thought you were blaming someone named Dan Dyer for making sure octal literals made it in. :o Also, I think Java/C# have potential as languages for low-level target applications and decisions that hurt those targets should, at the least, not be taken so lightly. - 280Z28
@280Z28: Edited to clarify about Dan Dyer, thanks. I'm not sure about Java and C# as low-level languages: how are they at taking raw bytes and making data structures out of them? A low-level language simply has to have ways to bypass the type system. Even so, removing the C-type octal notation will help things a lot more than it will hurt things. - David Thornley
(1) C# cases can fall through. There's a special syntax for it: "goto case B;" - finnw
[+15] [2009-01-19 15:32:31] Dan Dyer
  • The default access mode should be private.
  • Bytes should be unsigned.
  • The Cloneable interface should include the clone() method.

(2) Bytes shouldn't have autocast to ints (therefore no arithmeic, therefore no signed vs unsigned). Cloneable should not have been. Default private outerclasses and methods is probably over the top. - Tom Hawtin - tackline
(2) IMHO, It doesn't make much difference whether bytes are signed or not. However the range 0 - 255 is more useful than the range -128 to 127. - Peter Lawrey
(1) Heck, I'd be happy if ALL variable access was private too! - Bill K
(1) private and final for fields by default. - Peter Lawrey
[+14] [2009-02-03 08:30:12] Thomas

Checked exceptions are a problem in Java because they may break encapsulation.

There is an interview [1] worth reading with Anders Hejlsberg on Artima where he talks about that:

Anders Hejlsberg: Let's start with versioning, because the issues are pretty easy to see there. Let's say I create a method foo that declares it throws exceptions A, B, and C. In version two of foo, I want to add a bunch of features, and now foo might throw exception D. It is a breaking change for me to add D to the throws clause of that method, because existing caller of that method will almost certainly not handle that exception.


(1) And if you used unchecked exceptions the caller WOULD handle it? This isn't "breaking encapsulation" but rather "changing your api contract". - Mr. Shiny and New 安宇
(4) The point is that exceptions thrown by a method should not be part of the API contract, any more than the methods it calls, or the algorithms it uses. - John Saunders
(7) In my opinion the problem with the quote above is misuse of the exception. It you have a method that does-everything-and-anything the problem is not with the exceptions but with the overcomplicated method itself. The added features would most likely be better in another new method and changes are no longer breaking. You are correct in saying that interface contract does not depend on the implementation of this interface. However failure to do the action IS and MUST be part of the contract and checked exception is a great way to ensure failure are correctly propagated to client code. - Newtopian
Most complains of the sort I have seen involve examples where foo would let exception thrown from the methods it calls as part of it's implementation, and as such people want unchecked exceptions so they do not have to bother with exception handling at all. To me unchecked exception that simply fall through and checked exception stacking on method declaration are both a good example of conceptual bleed where your interface fails to capture the complete behavior of the system it tries to abstract. Checked exceptions is, so far, the only way I know to ensure the API contract is complete - Newtopian
@Thomas, At the JVM level there is no difference between checked and unchecked exceptions. IMHO all exceptions are the same at runtime and Java just provides some checks for you at compile time which you can work around or deal with as required. - Peter Lawrey
@Thomas: I think checked exceptions could have been made a useful construct with one addition to the language: the ability to specify "dontcatch" exceptions on a try block or method, such that if method Foo specifies dontcatch BlahException, then any BlahException thrown from any code called from Foo would be rethrown, wrapped in a RuntimeException. Note that if Foo also declared throws BlahException, then any blah exception thrown within the code for Foo would propagate up as a BlahException, but those from methods Foo calls would become RuntimeException. - supercat
[+12] [2009-01-24 00:01:12] dsimcha

Too much focus on simplicity at the expense of expressiveness. That basically sums it up.

[+10] [2009-01-19 15:19:34] Paul Tomblin

No destructor. I wish there was a standard (optional) way to say "I'm done with this, run some code", rather than relying on the finalize method that may never get called. I'm not talking about having to manage memory, just that when you do want to finish with something, there was a standard call to make which would do whatever clean up you wanted and then provide (maybe) some hint to the Garbage Collector that you're done with it. I'm sick of having some classes with a "close" method, and some with a "done" method, and so on and so forth.

There is a way to do this - have some other class call myObject.cleanUp() (or whatever) just before you release the last reference to the object. You're right that finalizers should be avoided as they're not a good idiom at all. - Andrzej Doyle
(5) There is a much better and more controllable way to handle it than destructors, look into references (weak reference, ...) - Bill K
(1) Agreed, doing things when leaving a scope is a really powerful concept even if it's not related to memory management. Scoped benchmarks, locks etc is great. - Laserallan
(2) Finalize is NOT meant for replacing destructors. - Mnementh
RAII would solve this. - Bernard
If there isn't one already, make an IDisposable interface and implement it on the relevant objects. Even without syntactic sugar like a using statement (C#), everyone will know what it means when you implement that interface and you won't me fighting with what to call the Dispose method (dispose() in Java?). - 280Z28
(3) Java 7 uses Closeable to indicate automatic resource management - KitsuneYMG
Java 5.0+ has Closeable and many resources have had a close() method from the start. What Java lacks is direct support for it, but there is nothing stopping you add a method to do this. - Peter Lawrey
[+7] [2009-04-11 22:58:30] Jordi
  • No operator overloading
  • No real array literals
  • Primitives are not objects
  • No decent multiple inheritance (I know there are problems, but they are fixable)
  • Too verbose
  • No decent way to declare "variables" constant unless they are primitives (i.e. you can still call 'setBar' on a 'final Foo foo')

Not necessarily things they did wrong, but things that I would have liked:

  • Closures and function pointers
  • Destructors
  • Possibility to return multiple values from a method

(11) +1 for operator overloading. Anyone who has ever used BigInteger will agree. - MAK
(11) -1 for operator overloading. Anyone who has ever used C++ will agree. - jdizzle
(10) @jdizzle: Just because a few idiots abuse operator overloading in C++ doesn't make it a bad feature. Also, if Java wanted operator overloading that was less prone to abuse, it could allow overloading of arithmetic and bitwise operators but not assignment and copy construction (where most of the abuse is in C++). - dsimcha
(2) @dsimcha I saw plenty of abuse of the arithmetic operators in C++. If '+' can append strings, why not collections? Think "RecList recList; recList += newRecord;" except there is validation logic in the overloaded operator. Yuck. - Kelly S. French
(3) @Kelly How does allowing me to do whatever I want with operator+=(...) differ from allowing me to do whatever I want with 'append(...)'? Both are arbitrary names for an action. Just because I think I know what append does doesn't mean I should skip reading the javadoc for it. The same can be said of operator+= - KitsuneYMG
@kts The system I worked on was a nightmare because it combined operator overloading with a liberal use of inheritance which made it devilishly hard to figure out which operator was going to be called at runtime. - Kelly S. French
@Kelly Wow. I never though someone would use virtual operators. Or override non-virtual functions. They deserve death. Possible by shoving iPads into uncomfortable places until they pop. - KitsuneYMG
(3) +1 again for operator overloading. I love it in C++, I still remember using it while I was declaring a mathematical Matrix class. Very useful, obvioulsy it should not be abused, but silly programmers can make a mess usinge any type of coding language even in Java. - Marco Demaio
@MAK IMHO BigInteger and BigDecimal tend to be over used. However, Java could support operator overloading for these classes specificity without having to make it available to every type and every operator e.g. + works for Strings. - Peter Lawrey
[+6] [2009-01-19 15:13:59] Dennis Cheung

JNI could be one of the worst in Java.

It is much much more time wasting if you compare it with PInvoke in .NET.

Yes, it's much easier to be better with 7 years of hindsight. - Lawrence Dol
But then again the ease of P/Invoke lead to many .NET applications not being able to run on pure .NET but depend on Win32 instead (= no chance for Mono). - Joachim Sauer
(1) It should be a decision of the programmer. Not the platform provider. Anyway, I hope mono will able run them some day later, think about WINE. - Dennis Cheung
(5) I'm glad it's not easy to tie java apps to a specific platform. Doing it would destroy the whole purpose of java. - Romme
+1. I actually find it easier (on Windows) to write a C# library to access the native functions via P/Invoke, expose an ActiveX object from the C# library then access that from Java using JACOB. - finnw
[+6] [2009-01-23 22:54:47] Peter Lawrey
  • Fields, parameters and local variables should be final by default and only mutable when set. e.g. var
  • There is no consistent way to make an object immutable. (Only references and primitives)
  • wait(long timeout, int nanos) on every object, even though it does not have nano-second precision and probably never will.
  • Object.getClass() returns Class<?> i.e. getClass() doesn't know what class it is at compile time. e.g new Integer(0).getClass() in code returns a Class<?> not Class<Integer> however when you compile the code it returns Class<? extends Integer>, thank you @Mr. Shiny and New
  • array types don't override toString() as so print something like "[B@ef172a" However, Arrays.toString(byte[]) would be a useful default behaviour.
  • Integer.class.isAssignableFrom(int.class) == false. int.class.isAssignableFrom(Integer.class) == false. Yet with autoboxing and reflections there is very few examples where this is the case.
  • @Deprecated are never removed, even if it has been deprecated since version 1.0.x

(3) Class<? extends Integer> c = new Integer(0).getClass(); compiles for me. - Mr. Shiny and New 安宇
(1) "Fields, parameters and local variables should be final by default" - Eh? I've always followed "make the common case the default," and that is not the common case by a longshot. - BlueRaja - Danny Pflughoeft
(3) It is not the common case because that is how people have learnt to program. If you get used to using immutable objects, that becomes the common case. Immutable objects have many advantages over using mutable objects which too many developers just haven't ever thought about (which is why I would prefer immutable to be the default) - Peter Lawrey
(2) For example, many of the built in data types such as wrappers are immutable and the ones which are not are clearly labelled Atomic or the like. Date is mutable, but most people assume its immutable. This only works because people treat Date as if it were immutable. - Peter Lawrey
It is easy to label an immutable field as the default and there not mutable. And it works until someone changes the code assuming the field is mutable, but you have assume the value won't ever change once set. Basically, there is no way to know if a field unmarked is safe to change without reading all the code. If it were specifically labelled mutable, you would know it safe. - Peter Lawrey
@PeterLawrey: It's not the common case because it's not the default, and you have to type extra. - Mechanical snail
[+5] [2009-02-03 08:52:35] Apocalisp
  1. Variables should have been not nullable by default.
  2. Fields and variables should have been final by default.
  3. There ought to have been a type for method references (first-class functions).
  4. Missing the ability to seal types (not classes, but types).
  5. Inability to do case-analysis on complex types (enumerations only, sorry).

You're wrong about being unable to seal types - that's what final does as a class modifier. - Lawrence Dol
(2) But oh so right about first-class functions. - Lawrence Dol
It's true that you can mark a class final to say "this type has no subtypes", but what you can't do is say "this type has these three subtypes and no others". I.e. you can seal individual classes, but not entire types. - Apocalisp
There is the zero-one-infinity rule. No three subtype case. - R. Martinho Fernandes
I wonder how you enforce the "one" case. - Apocalisp
(1) @Apocalisp: A type cannot be sub-typed if it has only private constructors unless those sub-types are nested in the super-type. You can exploit this feature of Java to (sort of) seal the types. - missingfaktor
(1) @Apocalisp, I agree that Field and Method should have been supported in the language rather than via a library. - Peter Lawrey
[+5] [2010-01-13 00:10:59] Viktor Sehr

Ugly looking default GUI, I think Java would gain a lot if they provided a nice default look-and-feel.

(1) Not so much of an issue now as it used to be, but the negative stereotype probably still sticks for many people. - Jonik
(1) Even due it's quite easy to change to the native LookAndFeel, I still think it's a problem that you can't provide a good looking, platform independent LookAndFeel. (Cause Metal is ugly) - Viktor Sehr
[+5] [2010-05-05 19:10:25] drawnonward

Java believes its own hype.

No way to take off the training wheels. Whenever I have to use Java I feel like I am on a kiddy trike.

It is overly difficult to reuse code. Other languages encourage decoupling shared functionality from a single object, but in java the only way is inheritance which is often blocked for other reasons. How do you add a method to String?

No first class functions. Not everything is always object oriented.

Tying the class name to the file name. This makes it hard to use the same file in multiple projects.

No pointers.

No preprocessor. Unless your projects are very simple or very isolated, having a preprocessor is invaluable.

No manual memory management. It is convenient to ignore memory management sometimes, but not to be forced to it.

No way to tell if an object implements a method. The information is there, but hidden because somebody might be allergic to details or something.

No way to call a method on an arbitrary object by name. Right now you basically have to make an interface for every single function, when that should just be implied.

No consistency in the core data structures. There are so many implementations of lists and maps and vectors and arrays and none are interchangeable.

Not cross platform. The one strength of java should be that once you port the virtual machine everything else just works, but that is not always the case in practice. I have one product for two platforms and very little code works on both. There is not a single file that I could use in both versions of the same program without some modification.

Java always feels so slow. You can argue that it is just as fast as this or that, but my perception is always that if it was not java it would be much faster.

(2) Your requirements would make Java an entirely different language. I don't understand why you'd want to use Java when C++ seems much more appropriate for you. - Tomik
(4) Sometimes we have to use a language we do not want to. - drawnonward
(2) Taking the training wheels off is harder with Java, but for each of the issue you mention there is a work around or library which does this. Perhaps there shouldn't need to be a work around, but there is nothing stopping you doing these. I admit, sometimes perception is more important than reality. ;) - Peter Lawrey
[+4] [2009-01-21 21:59:04] Filip Dupanović

A couple of years ago I appreciated Java more than I do today.

I fell deeply in love with their packaging. Today I despise it. A gazillion classes all over the place packaged in a way that would have very little sense hadn't you had experience armed with you. Check out the language ref for AS3 [1] and see what I mean. The 2nd day I started working in AS3 I wasn't going on google looking for tutorials on how to do something, I was already a natural, knowing instantly where that class that I never knew even existed, that did exactly what I needed, was located.

Java still has a great community, but it's not as intuitive getting involved in their communities as it is with other languages. Other languages have provided way better developer portals, way better and more resources.

Basically, Java got too big to handle, got big before they'd lain out everything for its growth. It's too bogged, too confusing. They used to be the forward thinkers in so many aspects, now they are good in few and in some we just wish Java would collapse once and for all.


[+4] [2009-02-03 19:19:24] Mr. Shiny and New 安宇

In JDBC the java.sql.Date class has no time component. This forces you to use Timestamp, which confuses Oracle when your dates are stored as Oracle DATE values.

Also I'm not crazy about how Java is packaged. It's annoying to have to set up class paths and jar files and don't get me started with EAR files and WAR files. There is room for improvement here.

[+3] [2009-01-19 15:10:46] Brian Knoblauch

I tend to get a little irked by the deprecation of good useful objects and their replacement with ugly, hard to use objects (example: Date & Calendar).

(8) Date was not "good useful", it was "simple and broken". - Michael Borgwardt
(1) I would be completely okay if they added JODA to the java API. - BlueRaja - Danny Pflughoeft
[+3] [2009-04-11 21:36:29] Bernard


While GC is incredibly convenient, an unpredictable GC is not suitable for certain applications. One such example would be hard real time systems. In a hard real time system a single unexpected delay can result in mission failure.

Examples of such hard real time system would be: fly by wire systems on a fighter jet, navigation systems on a missile, robotic arms that perform surgery, etc.

Also, getting killed in a real time video game is also a mission failure. You don't want to GC right at the moment the player pressed the "dodge the giant fireball that will kill my character and force me to redo the 20 minute long level," button. That is a very important button. (Although it has been noted that in multi-tasking OS you cannot control the task priority which could easily be worse than a large GC operation.)

Static Polymophism

Ignoring static polymorphism. Static polymorphism could go beyond "C++ like" templates, and it is a very useful optimization. Generics as implemented in Java is still dynamic and it loses that opportunity to eliminate run-time type checking where compile time type checking would is enough. Of course is possible for increased code size to reduce performance more so than dynamic types would. As with all optimizations it should be profiled.

Everything is in a class

Although nit picky, there are times when you just want a function. Currently in Java you must put such functions in a class as a static function. A better solution would be a function in a namespace. While a class can work like a namespace, classes cannot span multiple files and libraries.

(5) Java isn't the right tool for programming real-time systems. The argument about GC pausing an app is old; a modern JVM always doing GC, so you don't get long pauses anymore. Besides, if you run that game on an OS like Windows, you don't really have any control over process scheduling, anyway. - Barry Brown
Good point on the process scheduling, I'm still learning about real time systems. Regardless "long pauses" is a relative term, but I do see your point about Java serving a different purpose. For non-real time systems it seems to do a good job. - Bernard
Real time is best done in ADA or C. While Java can run real-time systems, but was not designed for them. - WolfmanDragon
GC certainly isn't a Java language problem, it's an implementation issue, and the GC can be selected independently of the language to handle various uses. Also, there are very serious solutions to the issue for hard real-time system, including IBM's Metronome collector:… - 280Z28
(1) there is no one tool that's perfect for everything. Java for real-time systems is just silly. GC is a really nice idea on the vast majority of java-friendly projects. that may be circular reasoning but there's enough projects that fit that to make it worthwhile IMHO. Polymorphism, OTOH, I agree. They sort of went half-a**ed between fully static C++-like and fully useful ML-style type derivation... - Brian Postow
@Bernard, If you want to minimise GC, don't release so many objects. Java doesn't make it easily or it libraries, but you can write a Java system which doesn't minor GC ever (and only GCs in when you want it to) - Peter Lawrey
[+3] [2009-04-11 21:45:23] Zifre

I like Java a lot, but mainly two things bug me:

  • No unsigned data types - I find that most of the time, it doesn't make sense for the data I have to be negative. Unsigned is like a form of documentation, and it also happens to double the maximum value.
  • No structs - mainly a performance thing.

Also I think doSomething() looks worse than DoSomething(), but that is merely a coding standard, and not really a problem.

(1) Structs are really not any faster than classes: the only difference is that every class-method pushes the this pointer onto the stack, and class-instances need to dereference to get the value. If anything, having stack-based instances would increase the performance much more than structs, but even that would be such a small increase it just wouldn't be worth it for the extra syntax/beginner-confusion. - BlueRaja - Danny Pflughoeft
@BlueRaja: Avoiding heap allocations and garbage collections is very important when writing heavily parallel multithreaded code. GC overhead will eat you alive there. - dsimcha
@dsimcha, I agree that using struct would decrease Object allocation, but I am not sure passing struct between threads is a great option. - Peter Lawrey
[+3] [2009-07-20 23:58:02] Peter Recore

Making up a whole new logging api (java.util.logging) to be the new standard was a mistake that annoys me. I have to create a subclass of a Formatter just to get output on only one line! What was wrong with log4j?

[+3] [2010-01-22 20:46:40] BlueRaja - Danny Pflughoeft

Not that important, but something I never thought about before today:


[+2] [2009-05-12 00:00:26] thSoft

There are serious downsides which result in boilerplate patterns:

  • type erasure
  • checked exceptions
  • inflexible catch clause
  • no default arguments constructor
  • JavaBean conventions
  • need for redundant type information
  • no observable collections
  • no covariance

...and so on.

(1) Observable collection types are a class library issue. New(ish) versions of the .NET Framework have an ObservableCollection<T>, but it's not a C# language feature and doesn't get any syntactic sugar. Is there some aspect of them that you'd like to see in the Java language as opposed to simply implementing them in a (possibly standard) class library? - 280Z28
Observable collections do exist, in both the standard API and third-party libraries. Example: javax.swing.ListModel - finnw
Thanks for pointing this out, but as far as I see, there is only a rather poor (Vector-backed) implementation of this interface, DefaultListModel. I know that 3rd party libraries exist such as Commons Events or Glazed Lists. - thSoft
"no default arguments constructor" do you mean there shouldn't be one? I don't like JavaBean conventions either, so I don't use them (if possible) - Peter Lawrey
[+2] [2009-07-14 20:33:20] Jason S

java.nio.Buffer, ByteBuffer, etc. are classes, not interfaces, and have no way of allowing you to wrap anything but arrays of primitive types (byte[] for ByteBuffer) in a Buffer so you can pass the resulting object to a method which uses a Buffer.

[+2] [2009-07-14 21:20:58] kd304

No public mutable BigInteger and BigDecimal for more performant compound operations and the way requests for them gets always turned down citing the evilness of mutable objects in multi-threaded application. Please then remove StringBuilder as well!

Using question marks instead of named placeholders in PreparedStatements - who wants to count each question mark all the time to check if everything got assigned?

Inconsistent usage checked/unchecked exceptions in the runtime: Integer.parseInt(String) unchecked, String.getBytes(String) checked.

Sub package cross-dependencies in the runtime: java.lang <->

[+2] [2009-08-08 20:16:16] bpapa

Failure by Sun to incorporate new APIs into the platform quickly. If you're new to Java, and want to do some logging, there are about 100 different ways to do it. Which should you use? Who knows. There's too many choices, and you have to find out which one fits your needs. There should just be one way to do it, or at least a recommended way to do it.

[+2] [2010-02-23 05:18:20] Kevin

Ones that have already been mentioned:

  1. No unsigned types - the worst thing here is that Gosling basically justifies this by saying that developers are too stupid to know how unsigned arithmetic works, so it's better to just not have them available.
  2. Primitives are not interchangeable with their equivalent classes. That is, an int is not an Integer and so on. The real killer is that if you have two Integer's that wrap the same value and you compare them, the comparison will return false since the Integer objects aren't the same object.
  3. Related to that, there's no operator overloading at all. I know people bitch about operator overloading, but they make life so much easier. They'd let Integer behave like an int, for one thing.
  4. Multiple inheritance. I'm willing to let this one slide since there are a lot of implementation nightmares involved, but it still lets you do things so much more cleanly. Sure it's abuseable, but if we removed everything abuseable from a programming language we'd have nothing left.

The one that hasn't been mentioned yet is the lack of basic enums. Sure, they added something they /called/ an enum in 1.5, but it's not. It's a neat construct, and it has its uses, but it's not an enum and it doesn't cleanly replace just having a bunch of constant int values.

There are other things that bug me, especially the things that make Java so slow, but those five are the things that irk me most from a strictly code development viewpoint.

[+2] [2010-05-05 19:37:16] Pavel Minaev

Java mixes up value and object identity equality by using the same operator == for both. Hence you have to use == for int, but equals() for Integer, and so on. A good example of a language doing this right is Python (value equality: == and !=, identity comparison: is and is not) and VB (value equality: = and <>, identity comparison: Is and IsNot).

[+1] [2009-01-23 22:28:44] Scott Stanchfield

[Hmmm... not sure why the downvotes...]

Java should not have used the same syntax as C++ with different semantics.

A couple of examples

  • meaning of "protected" is different

    • C++: "me and my subclass"
    • Java: "me, my subclass, and my package"
  • meaning of "Dog d" is different

    • C++: "d is an instance of Dog"
    • Java: "d is a POINTER to a Dog"

This causes a great deal of confusion with C++ folks who learn Java. I still see many people shocked when they hear that "protected" includes other elements in the same package...

(If you don't think Java has pointers, see

I'd like to point out that the downvotes you are getting is not because you said "Java has pointers" (Though pointers and references are not the same), but because we see the two things you pointed out as good things. - FlySwat
(3) Keeping bad habbits from C++ would be a huge mistake. C/C++ programmer can not expect all other languages to be compatible to them. Even C++ is being changed to remove many of its old mistakes (look up C++Ox). - Danny Varod
The "Dog d" convention for d being a reference to a Dog is used in many languages. The fact that all objects can be by value, reference or pointer in C++ can be very confusing. - Danny Varod
My point isn't that these are good things that Java missed; my point is that Java uses the same syntax as C++ to mean different things... - Scott Stanchfield
I agree on the naming schema @Scott - WolfmanDragon
[+1] [2009-01-23 23:54:43] asdfqwer

I'm by no means an authority for what Java is doing wrong, but from this rant on comp.lang.lisp [1] it looks like there is logic error in their exception handling. Is that a fair assertion?


(1) I think that rant's claims about losing the exception stack are exaggerated. Other than that, it seems to me the approach attributed to Lisp greatly complicates exception handling (it adds power, sure, but it greatly complicates it). For example, the article postulates that you could write code that the decides to resume on an exception 30 frames and two libraries deeper than your code ever contemplated. Sounds bad. Sure another exception will happen, but it sounds like a bug waiting to happen. - Yishai
[+1] [2009-04-11 22:37:37] Jason Gin

I don't like how collections in Java have a toArray() method that returns an Object[]. It's very difficult to cast between a primitive array and a collection.. You end up doing this:

ArrayList<Integer> list = callSomeWeirdAPIMethod();
Object[] f*ckedArray = list.toArray();
int[] realArray = new int[list.size()];
//...copy elements from f*ckedArray to realArray

where you can't do this:

int[] realArray = (int[]) list.toArray();

or even this:

Integer[] realArray = (Integer[]) list.toArray();

(5) Integer[] realArray = list.toArray(new Integer[list.size()]); - Dave Ray
(1) Well, of course you can't do that. realArray should be of type float[] ! sheesh. B-) - Brian Postow
+1. But it would be nicer if int[] implemented List<Integer>. ints are already autoboxed as Integers. I don't see why primitive arrays shouldn't be autoboxed in the same way. BTW Google's guava library has int[] realArray = Ints.toArray(list); - finnw
The collection classes needed to be broken down into read only versions so we don't throw UnsupporttedOperationExceptions just to get a read only list - KitsuneYMG
Apache has a library to do this but it should be supported in the language, or at least the JDK. - Peter Lawrey
[0] [2009-07-21 07:53:27] Jeroen van Bergen

One thing that bites me regularly is the fallthrough behaviour of the switch statement.

Reading the replies made so far, I notice the almost complete absence of multiple inheritance. It is mentioned only once, but used to be a subject of heated discussion a number of years ago. I'm wondering why this is the case. Do people feel it is not really needed? Do people no longer care?

Take a look at this blog post discussing C# for some of the reasons several languages have avoided them: - 280Z28
[0] [2009-08-06 03:08:44] WolfmanDragon

Lack of Class modifier Friend. One long and verbose class can be broken into two Friend-ly Classes in C++, but not in Java. A static inner class will do the same thing as long as the code never needs to be reused.

(1) Package visibility is Java's friend, though. - Pavel Minaev
[-2] [2009-02-03 08:07:37] Lawrence Dol

Non-resizeable arrays. Yes I know you can allocate another array and System.arraycopy() the original... but would it have been so hard to have, e.g., array.resizeTo(x), array.growBy() and array.shrinkBy().

And no way to make an array entirely final (it's reference and all of it's elements).

Edit: Arrays don't implement the Collection or List interfaces.

You have ArrayList for that. - R. Martinho Fernandes
@Martinho: Get serious :) - Lawrence Dol
what's wrong with ArrayList ? what can a simple array do that ArrayList cannot ? - Newtopian
(3) @Newtopian: Ummm, store primitive values without boxing overhead? - Lawrence Dol
[-2] [2009-02-03 09:03:00] Apocalisp

The collection hierarchy in the standard library is completely broken as designed. Just as an example, the List interface has 25 methods that you have to implement, and most of them mutate the list. Collections rely on the elements implementing equals and hashCode properly, which must be done by inheritance, which disfavours composition as a design strategy if you want your libraries to work with the standard library.

(3) To implement your own collection you can derive from AbstractList, which reduces the number of methods to implement greatly. - hstoerr
I don't understand your comment about implementing equals and hashCode by inheritance. What do you mean with "by inheritance"? - hstoerr
(2) AbstractList is still designed to be a mutable list. You can write an immutable implementation only by throwing exceptions at runtime on mutation attempts. By "by inheritance" I mean that those methods are meant to be overridden in subclasses. As a design choice, I want to avoid subclassing. - Apocalisp
[-6] [2009-01-23 23:55:47] flussence

In two words: Turing Tarpit.

Why is Java a Turing tarpit? - R. Martinho Fernandes
(1) There's a few good reasons at the top of the page. My own specific gripe is that it requires a disproportionately huge amount of boilerplate code. It's improving, I still find it far too long-winded to be productive in. - flussence
(1) You've obviously never programmed in C or Assembler. - Lawrence Dol
This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. - Seki
(2) @Seki: ok, thanks. I'll try to remember the site's current social norms next time I go back in time 3 years to post. - flussence
[-15] [2009-01-19 15:12:51] nes1983

Bundling .jar files: 1st: .jar files don't really have icons (wtf?!), then you cannot include .jars in .jars (omgwtffff). Together: write your code once, run it anywhere and write a 6-page manual for every platform on how to properly bring your UI up. Include sentences like: "we recommend setting the classpath. to do that, run msconfig in a shell"

Make a contract with the nearest suicide aids provider.

It's become a bit better when we the have the webstart, JNLP. - Dennis Cheung
Or an installer. - Tom Hawtin - tackline
(3) -1. jar files not having icons is a really really bad thing... lol - R. Martinho Fernandes
(1) -1 For kewld00d talk and "lack of icons". - Jan Jungnickel
(1) embedded jars? Yuck. Jar Jar runs screaming from the room. - tylermac