First, this is not going to be a LanguagePissingMatch, I hope this will be a genuine list of positive (and negative but constructive) comments about Java.
On JavaBandwagon, someone said: In short, Java is a great language, but there is a lot of hype and excitement from folks who don't understand why it's great.
So let's tell those folks in simple terms why its so great and why they like the language.
I'll kick this off with some trivial examples but there are many more experienced people than me that I hope will contribute with the more subtle points.
-- ChanningWalton
See also: FutureOfJava.
[Here is the current list of good and bad things]
Why Java is Great
- Simple grammar - Java has a very simple grammar familiar to anyone with experience in C and C++, which must be 99.9% of programmers. The BNF for Java has about 50 rules; that for C++, about 140. And C++ also has templates and a preprocessor in addition to the grammar. Java just got quite a bit more complex in 1.5 (excuse me, Java 5). They haven't even released a new version of the language spec yet.
- Portability - These days Java really does run well on all the popular platforms (Linux was a little behind, until Sun realized they needed them... now it's just FreeBsd, OpenBsd, and NetBsd lagging) (Too bad that Ruby, Python, Perl, Squeak don't work well on most platforms... Oh wait, they do!)
- Speed - The latest JIT compilers for Suns JVM approach the speed of C/C++ code, and in some memory allocation intensive circumstances, exceed it. (Too bad Ruby, Python, Perl, and Squeak don't even come close)
- Standard APIs - You can happily write your code knowing that the standard java.* libraries will be waiting on the client for it, assuming a recent enough version of Java is installed
- GarbageCollection - the programmer doesn't have to worry about memory (most of the time)
- VM - see WhyAreVirtualMachinesGreat
- interface vs. class
- CheckedExceptions (some people hate this, but its optional) (some ppl love it)
- single class inheritance
- singly rooted class hierarchy (the reason that lack of templates isn't a killer)
- no OperatorOverloading
- reflection
- Inherent support for dynamic linking and loading.
- Guarantees of binary compatibility w.r.t. changes to linked code.
- fast edit/compile/run cycle faster than what?
- I can only attest that this makes EclipseIde great. It is wonderful to be able to make small changes to a class and have the recompiled class linked into the running application for immediate testing. I don't know whether this is possible in other Java environments.
- broad industry support
- safe semantics -- no UndefinedBehavior in pure Java code
- Security model for restricted execution
- It's relatively easy to make programs that parse or produce classfiles (but not as good as lisp)
- MrBunny's Big Cup O' Java (By high-performance we mean adequate. By adequate we mean slow.)
- Code is fairly transparent: except for a bit of built-in magic to do with String, code never invokes methods implicitly. (By contrast it's in general impossible in C++ to work out in isolation what a statement will do.)
- No FragileBinaryInterfaceProblem
- JavaDocsForLibraries
Bad things (part of the language and library definition)
Note that there is also a list of JavaDesignFlaws.
- Java isn't Simple. (perhaps "Less Complex than C++")
- it has basic types, but no typedef
- You can wrap basic types in a class defining some abstraction. Typedefs are only really useful at hiding implementation details if you can treat classes in the same way as basic types - pass them by value, defining operators on them, and so on, as in C++ - but with Java's object model, you would still need to change a large amount of code if you had to change a typedef from using a basic type to using a class. Also, because the Java language specifies the size of basic types, there is no need for int32, int16 etc. typedefs.
- EveryObjectIsAMonitor. Why?
- Because it makes it possible to prefix a method with 'synchronized' and make the method thread exclusive. This bothered me until I realized that OO allows for throwing instances of objects into an environment and having them cooperate.
- Monitors (all objects) only have a single condition variable (themselves). Why?
- Why not? generally speaking, my JavaIdiom is never to use synchronized on a public method, anyway. I prefer explicitly making a private final Object MUTEX = new Object(); and synchronizing on that.
- the hard-core numerics community hates the floating point stuff (see[1] for the Java Numeric Library)
- Sortty to dissapoint the hard core numerics community, but generalpurpose languages are always going to need libraries of some sort to do numerics.
- why no import <type> as <name>? Every other modular language has it.
- The argument is that it makes code harder to read. However, it would help get around the java.awt.List/java.util.List nameclash headache.
- Actually, I think the real argument is a little subtler. One of the design ideas of Java is that they don't add features unless there is a very clear need. (Yeah, I know, this is imperfectly followed, but that's not the point.) This kind of renaming is designed to solve a problem that occurs rarely in practice. There's an existing (if cumbersome) solution inherent in the package system. And using import renaming can result in code that's hard to read, especially if it's abused. So they left it out. Personally, I rarely miss it - I don't encounter the java.{awt,util}.List problem because I haven't worked with AWT since Swing came out. I occasionally run into the java.{util,sql}.Date problem, but it's merely an annoyance.
- Then it's just a matter of time as external Java libraries become more common. It's really hard to keep code readable when the type names are 30 characters long. Appealing to authority, if NiklausWirth (who is so minimalist that he makes Gosling look positively baroque) allowed import renaming in his languages, then it's likely to be necessary.
- no OperatorOverloading. Not everybody likes it (with the most common objection being quite illogical: it's easier to make obscure or misleading syntax. Prove to me it's somehow less easy to name 'add' my divide_by method, and maybe I'll start believing it). Worse, Java has no ExtensibleSyntax? in general. Users of languages with real macro or syntax extension systems (e.g. Lisp, Forth, etc.) often swear by them - the ability to create a mini-language specific to the domain, whilst retaining access to the power of the host language where necessary, is a remarkably powerful approach to solving domain specific problems. Even better, the common underlying language allows one to plug together problems from many different domains. OperatorOverloading is a rather limited form of extensible syntax, but it is a useful one.
- no closures (see WhatIsClosure)
- But Java InnerClasses and anonymous classes often fill the need
- no templates/generics (but the work to define them looks like it may result in something good)
- There is no need for templates and generics. Five years of regular Java development, since 1.0, convinces me of this statement. The basic reason is that I am usually the one that puts things into my containers and I am the one who takes them out. I know what's there! There is one time I called add with the argument being a collection instead of addAll. The debuging took about five minutes. Five minutes over five years wasted because of lack of generics/templates. I rather spend that five minutes instead of being rigorous with a feature that is only relevant because in C++ the class hiearchy is not rooted in Object or Thing or whatever commonality.
- Oh my. I wrote the above comment. Java 1.5 came out the other day. Generics are nice. Thank you. Not that they were needed. I am pleased I could change underlying classes first and everything still compiles. Beautiful. What I am suprised most about is how clear my code still is compared to C++. Thank you.
- I had exactly the same experience. Generics allow you to code ProgrammingPatterns in such a way as the compiler wil cooperate with you in enforcing them.
- is AWT the best we can do? No, but unfortunately we're stuck with it. Swing, as good as it is, still suffers some from its dependence on AWT. Why is it so bad? See TheStoryOfAwt.
- Swing blows because there was a chick on the swing team with a smalltalk background. Being a chick in a team of guys, she got it all done her way - messages being passed around and whatnot. What guis really need is a transactional model.
- Plus, a GUI framework should strive to be language-neutral, not tied to any one programming language. In fact, the other services probably should be the same way. LanguageNeutralServices
- reflection is too limited
- * Reflection is limited indeed, but by deliberate design. I must agree with the designers that I have seen only very few cases where reflection really solved the problem better than usual code.
- Why are "primitive types" not objects? This is non-orthogonal. (subthread moved to JavaPrimitiveTypesDiscussion.)
- Why can't I pass objects by value? (see JavaPassesByValue) Because that would require implied copy constructors.
- Why can't I pass objects by reference? (see JavaPassesByValue)
- Unlike C++, there is no 'const' concept that prevents objects passed as parameters from being modified.
- You don't need 'const' in Java. Primitive values cannot be passed by reference, so there is no need for const primitive parameters. For objects, 'const' is used to define a subset of an object's interface containing those methods that do not modify the object. Interfaces like this can be declared using Java's interface keyword. Const-casting then becomes a cast from the ImmutableInterface to the mutable interface. There is also no need for the 'mutable' keyword. Just because you can work around not having 'const' doesn't mean it wouldn't be a valuable feature. According to a friend of mine, const was originally in the language spec and they dropped it in the interest of getting Java out the door.
- Constructors are a poor substitute for MetaClasses.
- There's no easy way to return multiple values from a method
- Except to encapsulate those values in a new object or put them in a collection
- There's no way to retrospectively add interfaces to classes: for example, to declare an interface with a get(Object) method, and then say that java.util.Map extends it. There is some research out there on doing this. I think OopslaNinetyEight? had a paper on it.. Compound Types for Java.
- No TailCallOptimization or tail-elimination for recursive calls. Okay, who's the Pizza-lover? (Really? I think it would be allowed for the virtual machine to detect tail-recursion at runtime, but perhaps not.) Haskell and Scheme lover, actually. Are there any JVMs that do tail-elimination? None that I'm aware of, currently. I remember hearing some of the HotSpot team at JavaOne '98 talking about the possibility of doing this at some point. -- glv
- * The IBM JVM implementation does perform tail call optimization, but I can't afford writing code that runs on a specific JVM only.
- PizzaLanguage has a way of doing it, but it is explicit -- mf
- No operator overloading, which means you can't define your own version of complex numbers, polynomials, or matrices, and use them transparently with normal numbers.
- No "pure" functions. Most agree that OO is not always the best solution for everything.
Bad things (implementation issues that should get better)
- dates are atrocious and grindingly slow. We had to write our own.
- the stream libraries can be inefficient because of constant creation of transient objects
- BillPugh? claims there are fundamental problems with the synchronization stuff
- The volatile keyword does not work as specified (although most (all?) implementations follow the intent rather than the letter of the spec, and so work correctly).
- external integration (i.e. down the the C level) is too hard.
Bad things (part of the surrounding ethos)
- The language is licensed; Sun refuses to publicly standardize Ditto for MS & VB {nobody is asking WhyVisualBasicIsGreat.}
- Sun shot down one their most important partners, Microsoft After MSFT broke the license agreement
- Sun snubbed the Blackdown team by handing their open source work to Inprise to "finish up" and publicizing its release without credit to Blackdown. Which they honestly and publicly owned up to and apologized for at JavaOne2000
- Some feel that the only difference between Sun and Microsoft is that Sun has yet to achieve a monopoly position. And some people are just MSFT apologists
C-lovers:
Lisp lovers:
PHP Lovers:
Etc. Lovers:
:-)
Sun consistently use the same (rather large) set of buzzwords to promote Java:
"Java: A simple, object-oriented, network-savvy, interpreted, robust, secure, architecture neutral, portable, high-performance, multithreaded, dynamic language."
(The Mary Poppins of computer languages!)
When introducing Java to students I usually list the keywords, talk about "simple", "object-oriented", and "interpreted". I refer the students to Sun's overview for the blow-by-blow account of these buzzwords: http://java.sun.com/docs/overviews/java/java-overview-1.html
--
How do you feel Java lives up to that set of buzzwords ? -- ChanningWalton
Well, it all-but-unarguably lives up to object-oriented, network-savvy, interpreted, secure (at least relatively speaking), architecture neutral, and multithreaded. I think it's simple, but others disagree. It's more robust than C and C++, for sure. It's mostly portable, and while it's less dynamic than Smalltalk, Lisp, and the like, it's much more dynamic than the languages that the majority of programmers had been accustomed to. That leaves high-performance, which (at the time that set of buzzwords first appeared) Java definitely was not. I think it will get there, and it's making progress, but I still would only classify the performance as "acceptable for many jobs". -- GlennVanderburg
(Most of the students "got" the VM idea, garbage collection, interface-vs-classes, and reflection. Few of them took to the idea of exceptions. --)
Something is only portable if it has been ported. Sun (on its bid to become the EvilEmpire?) promoted Java as the first platform-independent language, which is patently false. First, Java is the platform (the virtual machine should be the tip off), and it needs the VM to be ported. That being said, it has been ported quite a bit, even though I haven't seen a fully compliant VM yet. Hmm.. sounds like ANSI/ISO C. Just trying to debunk some buzzwords.. -- SunirShah
I'd have liked Sun to release a text-only JDK (with an explicit subset of the full API). This would greatly improve the availability of ports. Besides, not everyone requires a GUI.
Could you clarify this for me some guy? Are you saying that you'd like Sun to release a Sub-Java that would be all of java but only the text only sorts of display methods? Would you like them to develop a special text only virtual machine standard? Are you looking for ports of the VM to systems that don't support GUIs or ports of text display software to java?
I ask, because as for the JDK itself, I haven't done anything GUI with it ... I'm still fighting with polymorphism ... I fumble with code using a text editor and I display stuff using text only functions like System.Out.println() .... -- EricHerman
With experience comes wisdom, Grasshopper. I am by no means a Java guru, but I was able to make a simple output GUI for a multi-threaded app, to display output from each thread in a separate window, in less than a day -- Pete Hardie
Sun wants to encourage Java ports. Some people don't need the GUI. If people porting the JVM (and the rest of the kit) didn't have to worry about the GUI, it would be much easier for porters to keep up with Sun's releases. Say I wanted
to build a Linux based application server using current Java technology.
Chances are I couldn't, because the Linux JVM porters are still busy fixing
all that GUI code I don't need. Requiring two different JVM standards would be unfortunate though.
--
Has anyone looked at Java 2 Micro Edition (J2ME)? I haven't.
http://www.sun.com/consumer-embedded/cover/j2me.html
Yes I have and I downloaded the JBuilder "handheld express" tools which includes a simple PalmOS deployment tool and built a couple of simple apps myself. The available APIs are cut down (no floating point in the Math class for example, no AWT) but it appears you can build usable apps with it.
Ward asked me the question which I've repeated to everyone I talk to about Java: "What's good about Java?". Here are the typical responses:
- Exceptions
- Garbage collection and memory management
- Interfaces
- Object oriented
- Threads
- GUI
- Built-in networking support
- Strong typing and specified widening/casting
- extensively specified operator precedence/evaluation order
- Extensive libraries included as part of the language
- cross-platform portability
- primitive type sizes are specified and platform-independent
- primitive type conversions in expressions are specified by the language
- No messy signed/unsigned/short/long/double issues. Question: in C++ what size/signedness is the result of this: uint64*1000? See TemplatesForNumerics for a response. -- DaveWhipp
One irritation I have with Java, partially discussed above, is that because I cannot declare that a class implements an interface, I am forced to do unnecessary cloning for safety's sake. Given an object with a date attribute, I am forced to write code like:
public Date getDate() {
return (Date)date.clone();
}
If I could declare that java.util.Date implemented an ImmutableDate
? interface, I could write the method:
public ImmutableDate? getDate() {
return date;
}
I know that someone could do malicious casting, but I choose not to worry about that.
Should I anyway?
See ValueObjectsShouldBeImmutable. -- EricJablow
It's typical that a page listing all the good things about Java becomes a focus for nit-picking criticism of Java. How about going through all the benefits list ed at the top of the page and seeing how other languages compare?
Or put another way. Say you were about to embark on a BareMetal? project with complex interaction of clients, servers, databases and legacy (contradiction there, I know). Why on earth would you use any language other than Java?
Because trying to integrate with legacy systems in java is painful.
Other languages compile down to native code and are therefore faster (C, Fortran, several implementations of Common Lisp), have better libraries (Smalltalk), are more expressive (Lisp, Prolog, Smalltalk), mind-expanding (Lisp, Scheme, Smalltalk Prolog, Haskell), extensible (Lisp, Smalltalk, C even) or smaller (just about everything). Java isn't even interactive.You have to define a class, then compile it, before you can run it.There are lots of reasons not to use Java.
When you talk about complex interaction, you should bear in mind that "Perfection is attained, not when there is nothing more to add, but when there is nothing more to take away.", and "Complexity is the hallmark of stupidity."
These criticisms are being expressed, not because people think that Java
is on a par with Intercal.They are being expressed because of the
constant hype, and because other, better languages are being overlooked.
Java advocates should be more modest about their favourite language.
They have much to be modest about. -- DonaldFisk
-->> Why Java is all but great:
- Not even one innovative idea.
- This isn't true. Java's CheckedExceptions were innovative, or at least new to mainstream. They weren't necessarily good, though. Relying on 'innovative' ideas is risky - they might go well, but they also might ruin the language. A 'great' language can be created by only using old ideas in the right combination and permutation. There is a LOT of unexplored design space out there.
- Possible major security flaws: you wont ever hear Sun communicate on it. The "secured design" exist only on the text editor. Once compiled into byte code, it's handled by C/C++ runtime. No one actually knows how it is designed.
- Hidden features. No pointers? wrong, they are automaticly handled, no one know how (we can only hope for the best, not actually making it happen). Garbage Collection? it's actually a myth, you can't never tell when memory is deallocated or not. All you can know is when unused memory is candidate to garbage collection. Practically, GC results in permanent memory leaks, memory is freed at app's closing.
- Unless your application is very short-lived, your comments on GC are simply untrue. Developers can, and do, rely on GC. I'm not sure the quality of most Java Runtime implementations of GC, but I know that smalltalk implementations are good enough to GC for continuous live video and gaming.
- Langage structure is crap. While it's true that the grammar is not a big deal (thanks C), the high level nature of Java doesnt allow you to actually do anything with merely the basic language itlself (unlike C). You have to learn a thousand pre-built fonctions to get started, frequently badly designed.
- Using Java won't teach how to programm in the least. (Too much automatic stuffs, obligation to use ready-made code). This does matter as Java is a commercial product from a commercial company. It ties you to Sun's plan for Java. What if they discontinue their support to Java? If they run out of business? If they have a better idea instead? You have to start all over again, and in the worse case if you know only Java you'll have to actually learn everything in the programming field.
- Sun's implementation of JavaLanguage has been OpenSource under GPL (excepting a few non-critical packages) since 2007 May 08. A 100% free version by a third party, 'IcedTea?', was completed in 2008 June and has passed the certification tests. And there are plenty of other languages that use the JVM (EeLanguage, ClojureLanguage, ScalaLanguage, GroovyLanguage, PizzaLanguage, etc.) - plenty of people who didn't like the way Sun was taking Java and who decided to take it their own way, yet still take advantage of the widely distributed and portable virtual machine.
- And the "I'm not learning to program because I'm using ready-made stuff" line of reasoning seems utterly bogus. Programming, in real life, is (and should be) largely about learning and using existing services rather than rolling your own. Too many people come out of a CS education ready to 'roll their own' linked lists and dependency injection frameworks. While knowing how to do so is useful, the common NotInventedHere syndrome is a mental disease.
- Worse of all: it ties you to what Sun decide what you can do with Java.
- Java is OOP only, wich means by design very limited (unless you consider what marketing depts says to be pure gold. In that case, i suggest you type a few search on Google like "why OOP sucks", or "OOP is a hoax" just to hear something different).
- Java "evolves" at a constant rate. As im writting, it's Java 6. Only a bad-designed Money Oriented Language can evolve on such a regular basis. Is it so crappy that they needed 6 revisions in 15 years? If you don't know about, i invite you to learn about the evolution of other languages, such as C, Ada, Fortran, C++, Lisp, Scheme. Example: C is nearly 40 years old, it has been reviewed twice, and not in a way that Sun review Java.
- Sun developped the Java runtimes and interpreters in C/C++. If they actually use these languages for their commercial products, why would they want you to use something else? Hint: An intern note in Sun's labs FORBID the use of Java for their own apps. (i dont have the link, it's available on the net).
But after all it's true it's a cool language if you dont care about programming.
[Some good points, but it's more rant than rational critique and is lacking any proper references, which severely diminishes the credibility of the commentary. Some of the above is obsolete, such as the suggestions that Java is closed source. It reads like it was written by a technically weak but tolerably-engaged ComputerScience student -- his or her first language, no doubt, is C/C++ -- who is expressing his/her irritation at being forced to learn Java to complete a (say) 6CC097 Multi-Platform Distributed Systems assignment and has left it to the night before the deadline. I award the rant a grade of 'D'.]
What you say about my post is largely true =),
even if i dont agree on everything.
In particular, about the ready-made code. I didnt mean to say "Do it all yourself", wich is certainly impossible.
What i was pointing out is that trying to come up with your solution is the only way to learn how things works; possibly making them better.
This way you can understand what you use, and find if the library's code really fit your need.
So IMHO Java is not a great language to start with.
- [So Java isn't an ideal teaching language, because it doesn't force students to implement their own data structures, container classes, etc? If true, it's hardly a criticism of Java; maybe it is an appropriate criticism of your teachers' choice of teaching language. However, there is nothing to prevent your teachers from assigning you to implement your own data structures, etc.]
One important thing i forgot to mention (but that's may be just me), is the machine model behind the language.
IMO, a language must give you a clear machine model through its structure so you can understand the language/machine interactions.
I find it particularly lacking in OO languages (not just Java), because of the difference between the language philosophy and the way a computer actually works.
OO is certainly great for programm's conceptions, but can't replace what a low level procedural language can teach you about the actual machine you work on, like C, wich machine model is great (portability).
(On this topic, for those interested, i'd like to also mention "Assembly Language Step bu Step" -Jeff Duntemann).
- [Again, that may be an appropriate criticism of the choice of Java for certain teaching purposes. Java is primarily intended for production development of data processing software. It is not intended to be a low-level teaching language. Doesn't the programme you're on have an assembly language or computer architecture course or module? If so, I doubt it uses Java.]
This said, i admit i have been unfair with Java. What upset me is Java's marketing rather than the language itself.
And you guessed right, im a CS student. I'll try harder on commitment and technic, thanks for suggesting.
- [Part of the maturation process of a good developer is learning to first recognise, then ignore, and finally laugh at marketing bumf.]
Cheers.
[EditHint: Move criticisms to JavaCriticisms]
See also:
JavaIsTheNewCobol,
WhenShouldWeUseJava,
WhenShouldntWeUseJava
CategoryJava