Such strong opinions.<p><i>> GC sucks</i><p><i>> android app</i><p>Android's runtime is not the Java Runtime. I'm starting to think Oracle should have at least gotten some damages from Google for causing so many people to think that the stuff <i>running</i> on Android is <i>the</i> Java and getting people like this guy vocally misplacing the blame.<p><i>> name clash: X and Y have the same erasure</i><p>Programmer unfamiliarity. Consume a List<T> with one function.<p><i>> Methods With the Same Name as Constructors</i><p>Constructors are never void. Obviously, because they have to return the object.<p><i>> Inner classes Don't Work</i><p>This is a quip. What's the critique?<p>There are a handful of reasonable points but the overall product is not. Furthermore, the pre-emptive rebuttals make it clear that there's no convincing them.
My main problem with Java is the people who use it. More specifically the people who use it but have never used anything else and don't see anything wrong with that.<p>Java is a great virtual machine, good open source libraries, an ok language, and a terrible community of "best practices".
I lost it when the guy said don't use an IDE. What's the point of having a static type system when I can't use an IDE to see where a specific method is called.
A wise man once said.
"There are only two kinds of languages: the ones people complain about and the ones nobody uses."
.
I wish all the hate in the universe is converted to something more useful ;) .<p>But.. Oh wait. public static void main? seriously?
Hey guys, I'm the original author of that article, and I appreciate the comments.<p>A few points:<p>* I started this article about 8 years ago.<p>* I've been trying to keep it up to date, so your comments are being reviewed.<p>* If you really, really love Java, I'm glad you found something in life to get passionate about.<p>* If you intend to be a professional software developer, you need to broaden your horizons before you start calling yourself senior anything. Java is only one programming language in the world.<p>Feel free to email me at jgardner@jonathangardner.net. I've been putting this email up everywhere for a very long time so getting more exposure just helps train the spam filters that much faster.
If there were one perfect programming language, everyone would be using it already.<p>If a particular language were horrible in every possible way, nobody would be using it. If lots of people are using it, maybe you are not understanding why.
Which Java? Which JVM? Which libraries, etc.? JDK 8 bears little resemblance to JDK 2. The latest JVM bears little resemblance to the first ones. Java is old. It is a huge ecosystem with lots of warts and cruft. There is a lot of good stuff, however, in that ecosystem and it's so good that it runs a huge portion of the Internet. So, some good criticisms but too much missing the forest for the trees.
Nothing sucks at all aspects as same as nothing is great at all aspects. So, i cannot see any useful information comes from this article at all. So sad this person spends so much time to write a long article to hate a programming language. :-/
This reads a lot like the C++ FQA. That is, it looks like someone wants any possible excuse to complain.<p>Now, in fairness, the C++ FQA has a lot more detail, a lot more specification of reasons behind the ranting. I think the perspectives are both the same (whiny ranting), but the C++ FQA is a large step above this.
Are we using the same Java?<p>> GC Sucks So Badly, That You Should Avoid Using Memory<p>I'm assuming this is from before Java 8. The latest GC algorithms don't do this.<p>> Worst of Exceptions and Value Checking<p>Sometimes the correct thing to do is to throw an exception and other times it is to return a sensable value. An exception is an unrecoverable state, a null is a sensable value for when nothing exists. Something not existing and an unrecoverable state are two very different things.<p>> Won't cast an int to a long<p>Again, are we using the same language? This works. see code example at the end.<p>> name clash: X and Y have the same erasure<p>This is not sensable behavior but entierly avoidable. Objects contain data and then process them, then return the processed data to another object. The Java way of doing this is to pass "List<Long> listOfLongs" and "List<String> listOfStrings" to the constructor of foo and to have funcLong() and funcString().<p>> incompatible types<p>I've never seen this but I also suspect that this isn't an issue as I've never run into it and I've had interfaces in interfaces.<p>> static methods and members in a class<p>Static means the meaning of the method or object never changes. It will mean the same thing in every instance of usage. As such this makes sense. You never need to override a constant meaning as it will always mean the same thing.<p>> The "class" type is an afterthought<p>What does he mean by this?<p>> No control on member access<p>Use lombok. Not an issue and is fixed at compile time, not runtime.<p>> RSI<p>This makes no sense. An IDE is a tool that Java is deisgned to make use of. Locking yourself in your cave and saying it's bad isn't going to pursuade anyone.<p>> Camel Case<p>Nameing conventions aren't a reason a language is bad.<p>> Class-centric<p>That is the idea behind Java. The other concenrns not addressed by the title have been fixed by the Java 8 additions allowing you to treat one-method interfaces in Java 8.<p>> Iterators SUCK!<p>That is an implementation but it's fairly standard to just have tihs backed by some form of collection and see if there is data left in it. I usually use an index in an array and see if I have run past the end of the array.<p>> foreach doesn't take iterators<p>Yea this is crap.<p>> Function Pointers -- Missing<p>Java 8<p>> Constructors can't call each other<p>Again see the code at the end.<p>> Methods With the Same Name as Constructors<p>Yea that's allowed, I don't see what's wrong with that. It's a real function name so it should be allowed. I've never accidently made this error.<p>> Run-time Dispatch: Fantasy<p>This is a design pattern issue but you're meant to use the highest or lowest version of an abstraction. From there you can ideally handle it in a generic way or if not you can use if (x instanceof Object) to filter out specific cases.<p>> No Globals means Frameworks<p>This is where decorators and static/singleton classes come in handy. You can do some amazing things with decorators, singleton/static classes, and if you need it a bit of reflection.<p>> import is Useless<p>You can just use the fully-qualified name of the other class and it will work fine. I've had maybe one instance where my naming conflicted with another package but that was a rare case.<p>> No List Literals<p>Arrays.asList<p>> Inner classes Don't Work<p>I don't know what he means as this works perfectly fine for some design patterns. Inherit state? No way. Provide impelemntations of an abstract/interface for a specific object? Yes way.<p>In ArrayList it is perfectly fine to make an ArrayListIterator as they are the same bits of ideas and as such should be in the same file.<p>I also prefer state enums to be defined in a class.<p>> Java is So Hard People Prefer to Write Code in XML, Jython, Scala, and Clojure<p>I don't do this only """ENTERPRISE""" Java developers do this. There's a lot of great work being done moving away from this mentality but there is still a lot to be done.<p>> Speaking of the JVM...<p>I'd love some numbers on these claims.<p>> DNS Client Implementation<p>Yea this is a problem. It's in here for compatability. There are many libraries implementing this better at the moment.<p>> Sun Microsystems May Sue You<p>I don't know if this applies to OpenJDK.<p>> Why Use Java at All?<p>Why use any language at all? Write binary and opcodes (like I've been doing in my CPU project). It's very fun!<p>In seriousness Java gets concurency right and I've not found another language that lets me write concurrent code like this ever before. Very nice platform to run on and one of the worlds best VMs. Everything is simple and documented well. I don't need to read a novel to get something working. I can think of a class, type that a control-space on my IDE, get a list of classes, find the one in the right package and move on. No google, no searching, just tooling and built in documentation. What's even better is most of the language is implemented in Java! I have the sources downloaded so CNTRL+Click and I can see everything's implementation! I'd love to see a python dev do that (I cant and I've been writing python for years).<p>I'll be emailing the author at this email: jgardner @ XXX .net and giving him this comment. I hope he can rebute some of these points.<p><pre><code> class Test {
private final int i;
public Test(int i) {
this.i = i;
this.test(i);
}
public Test() {
this(10);
}
private void test(long number) {}
}</code></pre>
Argumentum ad Populum applies here. A carpenter extols the virtue and efficiency of the nail and berates the screw and clip for its burdensome application until his roof flies off in a hurricane.
Yes, java Sucks. But in many real and very important ways it sucks less than any of the alternatives. Especially considering the age of the language, and how backwards compatible it has been over the last 12 years.<p>Sure the eco system went all XML, but to be honest is the current JSON craze so much better? Yet this XML heritage is not something one must suffer through these days.<p>GC pauses, know your tools. Azul Vega was a thing in 2005 which means GC pauses are an option not a requirement. Of course there is the whole family of JavaRT as well and things like IBM metronome. If you have an big project burning engineering hours on Java GC they should look further afield. Sure most of these tools cost money. You think the extra hardware needed to run most of this stuff in Perl is cheap?<p>Considering where python and perl went in their 5->6 and 2->3 migrations even Java 1.4 to 1.5 was smooth. Heck even the annoying into of assert as a keyword in 1.4 was painless compared to those. I know of 2 projects that even with much more man power thrown at it have difficulty moving from Perl 5.8 to 5.12 and beyond. Gosh its like WebSphere migrations from 3 to 4 where unique in that regards, not...<p>Look I understand, we all hate that crap java code some consultants and solution experts wrote and that we need to deal with. But to be honest, equivalent consultants and solution experts with Perl, C, Python or JS don't create any better solutions. In someways Java pays the price of it being practically so much better that these teams in their enterprise constrains actually get something out of the door. Unlike, many other teams. Crap that ships is much better than the stuff that never got anywhere.<p>The hasNext and next methods are very nice. Because the author assumes all calls to next must be consumed. Well that is not true, and then having hasNext return a boolean instead of an expensive object (e.g due to remote calls) allows for lots of nice optimisations. Throwing exceptions for normal results is a horror that is too common in Python, e.g. urllib2 and 302 redirects.<p>This actually is rant of someone who does not really seem to know better. Yes there are some good points in it regarding generic erasure. And it is a pain, but on the other hand it made the migration possible.<p>Hey if you don't like longs and int casting rules just use BigInteger everywhere. Sure its slow, but so is the cpython and mri ruby implementations. 32bits is not the same as 64 and the Java Memory Model can be a rude awakening if you use longs where you should have used ints.<p>The camelCase thing, use an better tool ctrl-alt-R and its done consistently and correctly.<p>Things that would be nice too have in Java do exist. Getting Function etc.. in Java8 would have been great a decade ago. Rust borrow checking would be nice as well as a change in that locks operate (i.e. consuming a function that is called on the data) instead of the otherway round (i.e. like Perl6 locks)<p>The advice to use Vanilla C as an option. A language where the equivalent of following is undefined and can do anything? Including rm -rf!!! Sure no implementation calls rm -rf on undefined behaviour, except every hacker coming in via a memory corruption bug. A class of bugs that is not present in other languages, and why it should not be your first port of call in the normal circumstances.<p><pre><code> public class WhyIsThisUndefinedInC {
int[] a = new int[]{Integer.MAX_VALUE};
public test()
{
new Thread(()->(a[0]++).start();
new Thread(()->(a[0]++).start();
System.out.println(a);
}
}
</code></pre>
In any well defined language you can have 3 outcomes, considering the total lack of locking etc... C gives you infinite!
Heck moving a small C code base to a new compiler/libc combo is a massive undertaking in technical debt reduction.
Any of the other languages, except haskel lack a memory model that is sane and useable (or any at all). When you can easily have 144 cores in single box that is not a great place to be in!<p>Sure we all hate Oracle, and their Sales teams. But on the other hand most of the time the customers deserve the sales team. Oh yeah I know its dirty to actually make money on Software it needs to be sponsored by privacy invading ad companies, or written by PostDocs with a lack of job stability. The JVM is solid, and WORA is true for certified Java TCK passing implementations. Android is not one of those.