There are several myths perpetuated by Java. Perhaps you can simply call them "biases". It's certainly not the most modern language but like most things, it's what you make of it. Here's my rebuttal to a few:
1. People equate Java IDEs with Eclipse and all it's problems. This one drives me the most nuts. IntelliJ is like night and day compared to Eclipse. I honestly don't understand why anyone uses Eclipse.
For years I've listened to Eclipse apologists for things like:
- Maven integration doesn't work. You need to add custom directives for m2eclipse (in IJ, you just open a pom.xml and you're done);
- Previously, there were two Subversion plugins for Eclipse and neither of them worked entirely right. VCS integration in IJ is excellent;
- Find and Replace across files is awkward and slow in Eclipse. It's fast and efficient in IJ;
- At Google, it's a running joke about Eclipse grey-screening (with our custom build processes and dependencies and so forth) to the point where it's been described as "turn-based programming". We can use IJ too and it has good Google integration but less resources dedicated to it. Still I've found it generally far less problematic;
- Am immense list of subtle improvements over Eclipse. Even something as simple as scope selection. Keep pressing ctrl+W in IJ you select the parameter, then all parameters, then the function call, then the block, etc. There is a similar(ish) command in Eclipse you can bind to a key but it's just not as good. That's just one example;
2. Java means using bloated frameworks like JSF, EJB2, etc. It does not. For example, I'm currently using Spring MVC (I haven't found a good relatively lightweight Guice-based Web framework yet) and Objectify on AppEngine;
3. You can't do closures in Java. You can. It's just incredibly verbose. Guava [1] is pervasive in Google. I highly recommend it. So you can write:
List<String> uppercase = Lists.transform(inputStrings, new Function<String, String>() {
@Override
public String apply(String input) {
return input.toUpperCase();
}
});
Granted it's much terser in, say, Python:
uppercase = map(lambda x: x.upper(), input)
or (my personal preference):
uppercase = [x.upper() for x in input]
But more on this in (4)...
4. There is a lot of boilerplate in Java. There is and there isn't. Empirically there is but it doesn't matter. Take the above function. I type (in IJ):
List<String> uppercase = Lists.tr (autocomplete "ansform(") new (ctrl+space fills in the entire Function<> definition with correct types)
Same for getters and setters. I press alt+insert, getters and setters and select the ones that have them. You can also auto-fill equals, hashCode and toString methods (although the Guava versions of those don't seem to have a generator).
5. Java means using checked exceptions. While I also loathe checked exceptions, this simply isn't true. It's one reason I like Spring. It tends to wrap most checked exceptions in unchecked ones (eg DataAccessExceptions instead of SQLExceptions).
6. IMHO Maven is great. Previously there was Ant and of course everyone thought their installation was different or they had their own preferences about where files should be. I like that Maven is "opinionated". It means you can go to any Maven Web project and know where to find things. YMMV.
Anyway, back to the issue at hand...
I've spent years working in such companies. It does tend to be a quagmire of mediocrity and politics but not always. We, as engineers, tend to forget that the easiest way to get anything done in such a company is to make a business case for added productivity, cost savings, risk management or whatever. Once you master this trick you can pretty much do whatever you want. It's simply the language the higher ups tend to speak.
Also, people don't tend to give enough credit to just how hard some of these jobs can be. Business processes and data migrations are incredibly tedious and they need to work.
Also, no matter how bad systems might be engineers tend to underestimate the ability of people to make them work. As engineers we tend to want to automate people out of pretty much everything we can. Often having some person look at something or correct something is far easier, cheaper and less risky than any automated solution or systems change.
Regarding #4, the worst aspect of boilerplate is reading it, not creating it. Boilerplate is just visual noise that makes it harder to see what the code's actually doing.
I'm not saying that your Java example is hard to read per say, but those extra lines of code add up, slowing down comprehension speed.
> 3. You can't do closures in Java. You can. It's just incredibly verbose.
It looks like you're confusing closures with lambda expressions. That's an example of (a more verbose functional equivalent of) a lambda expression, but it isn't a closure.
Java's anonymous inner classes can close over variables in enclosing classes, but they can capture only final variables directly from the enclosing lexical scope. So Java actually does not support true closures.
While I agree about the parent confusing closures and anonymous functions, it is possible to use anonymous inner classes as such if the final variable is a single-element array.
1. IntelliJ forces you to manually build your project. This is enough to force me to use eclipse despite all its problems
2. Sure, you don't have to use the frameworks, but they're one of Java's big selling points. If you didn't want them why would you use java?
3. I think you make the point for me. Sure, closures aren't impossible in Java, they're just much harder than they should be.
4. Boilerplate isn't just there when you write it, it's there when you read the code, which is much more important. The one major live bug I introduced was when I accidentally replaced a getter that had some code in with an autogenerated one.
5. It is true in that there are a bunch of standard library methods that throw checked exceptions (e.g. file I/O), so like them or not you have to handle them.
1) IntelliJ automatically recompiles your project in the background.
Its only when I do something drastic like changing dependencies that I have to hit the 'build' button.
I think IntelliJ gets this balance right.
Why should continual/incremental compilation be part of the IDE?
You can do this in a separate process, the IDE only needs to detect that some .class files have changed and refresh the metadata of those files.
Eclipse support for this is sure nice, but then I hate Eclipse for being bloated, with a sluggish interface and shoehorning such features on top is the reason why Eclipse is the way it is.
The IDE is supposed to be integrated, and compilation is one of its main responsibilities. I don't really care how it's accomplished, but I can't write java without "new errors show up in my IDE whenever I hit save". If there's an easy way to set up this separate process malarky then I'm interested.
I'm currently using Spring MVC (I haven't found a good relatively lightweight Guice-based Web framework yet)
I'm experimenting with Guice+Jersey+Angular.JS. It's a nice combination (if you want to do JS applications rather than the traditional MVC thing).
I've tried Sitebrickes[1], but the lack of documentation was a problem.
5. Java means using checked exceptions.
I think most people now accept that Java should have defaulted to using unchecked exceptions, and checked exceptions should only be for very rare cases. It's a mistake, but you are right: things like Spring make it a lot better in that regard.
Jersey actually has reasonable support for the traditional MVC thing too, you just return a Viewable from your actions [1]. I think out-of-the-box Jersey only supports JSP templates but it's easy to write custom view processors, I hacked one up for Mustache templates a few months ago [2].
1. People equate Java IDEs with Eclipse and all it's problems. This one drives me the most nuts. IntelliJ is like night and day compared to Eclipse. I honestly don't understand why anyone uses Eclipse.
For years I've listened to Eclipse apologists for things like:
- Maven integration doesn't work. You need to add custom directives for m2eclipse (in IJ, you just open a pom.xml and you're done);
- Previously, there were two Subversion plugins for Eclipse and neither of them worked entirely right. VCS integration in IJ is excellent;
- Find and Replace across files is awkward and slow in Eclipse. It's fast and efficient in IJ;
- At Google, it's a running joke about Eclipse grey-screening (with our custom build processes and dependencies and so forth) to the point where it's been described as "turn-based programming". We can use IJ too and it has good Google integration but less resources dedicated to it. Still I've found it generally far less problematic;
- Am immense list of subtle improvements over Eclipse. Even something as simple as scope selection. Keep pressing ctrl+W in IJ you select the parameter, then all parameters, then the function call, then the block, etc. There is a similar(ish) command in Eclipse you can bind to a key but it's just not as good. That's just one example;
2. Java means using bloated frameworks like JSF, EJB2, etc. It does not. For example, I'm currently using Spring MVC (I haven't found a good relatively lightweight Guice-based Web framework yet) and Objectify on AppEngine;
3. You can't do closures in Java. You can. It's just incredibly verbose. Guava [1] is pervasive in Google. I highly recommend it. So you can write:
Granted it's much terser in, say, Python: or (my personal preference): But more on this in (4)...4. There is a lot of boilerplate in Java. There is and there isn't. Empirically there is but it doesn't matter. Take the above function. I type (in IJ):
Same for getters and setters. I press alt+insert, getters and setters and select the ones that have them. You can also auto-fill equals, hashCode and toString methods (although the Guava versions of those don't seem to have a generator).5. Java means using checked exceptions. While I also loathe checked exceptions, this simply isn't true. It's one reason I like Spring. It tends to wrap most checked exceptions in unchecked ones (eg DataAccessExceptions instead of SQLExceptions).
6. IMHO Maven is great. Previously there was Ant and of course everyone thought their installation was different or they had their own preferences about where files should be. I like that Maven is "opinionated". It means you can go to any Maven Web project and know where to find things. YMMV.
Anyway, back to the issue at hand...
I've spent years working in such companies. It does tend to be a quagmire of mediocrity and politics but not always. We, as engineers, tend to forget that the easiest way to get anything done in such a company is to make a business case for added productivity, cost savings, risk management or whatever. Once you master this trick you can pretty much do whatever you want. It's simply the language the higher ups tend to speak.
Also, people don't tend to give enough credit to just how hard some of these jobs can be. Business processes and data migrations are incredibly tedious and they need to work.
Also, no matter how bad systems might be engineers tend to underestimate the ability of people to make them work. As engineers we tend to want to automate people out of pretty much everything we can. Often having some person look at something or correct something is far easier, cheaper and less risky than any automated solution or systems change.
[1]: http://code.google.com/p/guava-libraries/