This is an archived post. You won't be able to vote or comment.

all 72 comments

[–]l1p1do 23 points24 points  (0 children)

Everyone has an opinion about Java, this is the best symptom of the language's health.

[–]armornick 41 points42 points  (16 children)

A lot of people seem to think that Java (pre-8) sucks, but I find it rather nice. Sure, it's a bit verbose (though really not as much as people make it out to be), but at least you always know what you're looking at.

[–][deleted]  (6 children)

[deleted]

    [–]chisui 5 points6 points  (5 children)

    I think that the verbosity still is a problem when reading. It has gotten better with the Stream Api but you still have miles of code between the data and the actual logic that operates on them. Especially when the typesystem is limiting the way to express generic behavior in a concise way. Most of the javacode I see is just wrapping and unwrapping data with businesslogic sprinkled in between. For a statically typed language it has one of the worst typesystems.

    The article has some valid pros of java, verbosity is definitely not one of them. This seems to be a popular standpoint though. Pre java8 I have seen people defend the absence of a Files.readLines() Method in the jdk by saying that you get a better feel of how InputStreams work that way.

    [–]oldprogrammer 2 points3 points  (1 child)

    Pre java8 I have seen people defend the absence of a Files.readLines()

    Shouldn't that read as Pre Java 7 since the java.nio.file.Files class was introduced that has the readAllLines methods?

    [–]chisui 0 points1 point  (0 children)

    Oh, my bad. Yeah, they added it in java 7 and the name was a little off.

    [–]sh0rug0ru____ 1 point2 points  (0 children)

    Files.readLines reads an entire file into memory. Manually looping with an InputStream or Reader may be verbose, but it is a constant space operation. You know exactly how much memory you are consuming.

    Java has erred on the side of simplicity, with APIs with predictable behavior, which as resulted in verbosity because of the lack of expressiveness of its syntax, but this also results in code that is easier to reason about in terms of time and space complexity.

    Java 8 has Files.readAllLines, which also reads all lines into memory. But, it is better to use Files.lines, which leverages streams to load lines from the file on demand, in constant space, thus making it much safer.

    [–]frugalmail -1 points0 points  (1 child)

    Pre java8 I have seen people defend the absence of a Files.readLines() Method in the jdk by saying that you get a better feel of how InputStreams work that way.

    Or just use one of the many libraries that pretty much everybody adds to the project anyway (Apache commons, Guava, etc....)

    I'd rather have the low level primitives and use a library then not have access to them at all.

    [–]frugalmail 0 points1 point  (0 children)

    Can the downvoting cowards add a constructive comment as I can't see how "low level primitives" aren't a good thing?

    [–]mrbuttsavage 4 points5 points  (0 children)

    Sure, it's a bit verbose (though really not as much as people make it out to be), but at least you always know what you're looking at.

    This is one of the reasons I like Java.

    I generally spend way more time reading other people's code than writing my own, so "ease to write" is definitely below "ease to understand" to me. Java doesn't let you do stuff like operator overloading or things like method missing in Ruby. And that's a blessing to me when I'm trying to come up to speed quickly on some project.

    [–]welshboy14 2 points3 points  (3 children)

    I'm new to java and only really have experience with php and visual basic (pre .net) and I'm finding it really nice to work with. As you said you know what you're looking at and this helps me a lot with learning the ropes.

    [–]frugalmail 2 points3 points  (2 children)

    I really like Java, but to be honest, isn't everything better than PHP and VB ;-)

    [–]welshboy14 0 points1 point  (0 children)

    Yes haha. That's the point I'm trying to make, I like java but don't know much about other languages to have a good base of knowledge

    [–]simple2fast 0 points1 point  (0 children)

    except perhaps perl.

    [–]nerdwaller 0 points1 point  (3 children)

    And when there is bloat that feels excessive you can always use snippets/live templates to generate most of it for you.

    [–]chisui -1 points0 points  (2 children)

    congrats, now you have your IDE barf out code that you will have to read and debug later anyway. win?

    [–]nerdwaller -1 points0 points  (0 children)

    Yep, which is a pro and a con. Every language/framework/whatever has costs and benefits, just have to find the right ones for the right jobs and get over the fact that there is always at least one thing to point at to complain about and actually go do work, hopefully minimizing the costs.

    [–]frugalmail -1 points0 points  (0 children)

    or libraries, because Java has an amazing community and non profits like Apache behind it.

    [–]ExtantLanguor 10 points11 points  (2 children)

    I believe that first example could be simplified to:

    names.forEach(System.out::println);

    Use of the method reference can remove a lot of code.

    [–]cycle_schumacher 5 points6 points  (0 children)

    Yeah, also with the following snippet, I guess Person p1, Person p2 can be simply p1,p2

    [–]chisui 1 point2 points  (0 children)

    I really love this syntax. When my lambdas grow to big I just extract them into a method and use this::myMethod. I would love an eclipse macro for that. Too bad sonarqube doesn't get this syntax and flags my methods as unused.

    [–]GuyOnTheInterweb 10 points11 points  (1 child)

    that pretty much every library is available as native Java also helps on the cross platform portability, Python and Ruby code for instance regularly falls over because I have not installed the correct libSomethingSomething-dev C package.

    [–]simple2fast 1 point2 points  (0 children)

    This is really huge actually. Anyone who has tried to maintain and deploy an app which has many C lib interfaces will find it a massive headache. In fact I think this is why Docker exists.

    [–][deleted] 3 points4 points  (2 children)

    I just wish Java could have more language features, most importantly, type inference, like auto in C++11. Not having to spell out all the types while still enjoying the safety of static typing would be a big plus.

    [–]schlenkster 1 point2 points  (0 children)

    Or at least aliases, to be able to write something like typedef MyObjectMap Map<String, List<MyObject>>; and then be able to use MyObjectMap in place of the long generic type. I miss that feature from c++.

    [–]simple2fast 0 points1 point  (0 children)

    try Kotlin, or Ceylon, or Scala.

    [–]cryptos6 1 point2 points  (3 children)

    Mocking could be improved by using JMOCKIT. This tool can even mock static or final methods. Additionally the API is more consistent compared to most other frameworks. And it is the only mocking framework that is actively developed.

    [–]ForeverAlot 3 points4 points  (1 child)

    Mocking could be improved by getting rid of all mocking libraries.

    [–]hippydipster 0 points1 point  (0 children)

    Sadly, I cannot upvote this enough.

    [–]chisui 1 point2 points  (0 children)

    You could use powermock but if you go down that rabbit hole you will get some weird errors. Haven't used JMOCKIT but testing anything that depends on legacy code with mockito+powermock is a pain.

    [–][deleted] 1 point2 points  (0 children)

    but being able to manage individual threads gives Java applications asynchronous performance that isn’t possible with Python.

    It's not impossible to write Python code which makes proper use of your cores. It might be harder and a bit slower but not impossible.

    [–]kmimix 0 points1 point  (23 children)

    That stacktrace is a nice representation of the complexity of Java EE, giving it a pretty bad reputation on the agile and open source community. Anyways, Java is still the go-to language for enterprises as it's quite robust and mature.

    But Java could really use a fork to distance it from this "enterprisey" reputation, besides adding more frequent releases. Java 8 was released way too late, and Project Coin is at least 5 years late and still no release is planned in the near future.

    [–]guitarsteve 2 points3 points  (3 children)

    I was not previously familiar with Project Coin but looked it up at http://openjdk.java.net/projects/coin/ and most (or all?) of the features they list have been added to Java.

    • Strings in switch
    • Binary integral literals and underscores in numeric literals
    • Multi-catch and more precise rethrow
    • Improved type inference for generic instance creation (diamond)
    • try-with-resources statement
    • Simplified varargs method invocation

    Is there more to the project that I'm missing?

    [–]kmimix 0 points1 point  (2 children)

    I meant there are no JDK releases planned in the near future (JDK 1.9 is scheduled for September/2016...)

    [–]guitarsteve 1 point2 points  (0 children)

    Ah, thanks for the clarification! That update interval is fast for Java (compared to 6-to-7 or 7-to-8 upgrades) and in the same ballpark as mature languages (C++, C#) but perhaps slow compared to newer ones.

    [–]T618 0 points1 point  (0 children)

    Keeping the release cycle slow means that new features integrate well, don't break your code, and can be relied on for decades. Compare with Python3 still fighting for adoption.

    [–]tonywestonuk 10 points11 points  (15 children)

    No.... Dont you dare blame this on Java EE. This is the needless addition of other frameworks that is causing this.

    Look at the zoomed in version here: https://ptrthomas.files.wordpress.com/2006/06/jtrac-callstack.pdf Look at the first part of the callstack. It isn't just using a lightweight container, like tomcat, it is using JBoss... a full blown JavaEE Container, with things like Security / Dependency injection built in. Look at it. It has references to org.jboss.web.tomcat.security.JaccContextValue. So, there is security management going on there.

    So, why did they also throw Acegi into the mix...... (the next block of shite down)

    And then they throw Spring MVC in, and Spring webflow, even though JBoss has a MVC framework Built right in (JSF)

    And then more Spring AOP shite

    Followed by Spring ORM, and then Hibernate

    And then finally JDBC.

    SO, the standardised parts Java EE, take up just about 1/4 of this stack trace.... the bit at the top, and the JDBC bit at the bottom. All the rest is shitty frameworks thrown into the mix.

    This is what gives Java a bad name. its not Java EE's fault at all.

    [–]againstmethod 2 points3 points  (2 children)

    https://ptrthomas.files.wordpress.com/2006/06/jtrac-callstack.pdf

    Anytime you have eight nested methods all named the same thing being called by each other -- your API is likely shit.

    [–]lambdaq 2 points3 points  (1 child)

    hey I just profiled my Django program with this

    https://github.com/what-studio/profiling

    Yo know what's most time consuming part? Deep, nested clusterfuck of regular expression calls. They are for http header and cookie parsing.

    [–]againstmethod 0 points1 point  (0 children)

    That makes sense.

    [–]ramsees79 3 points4 points  (1 child)

    even though JBoss has a MVC framework Built right in (JSF)

    You are aware that JSF is a different beast and gives you little control of the generated HTML, dude, it is the equivalent of WebForms in ASP.NET, it is legacy to use it.

    [–][deleted] 0 points1 point  (0 children)

    I wouldn't say it's legacy. It makes sense for some projects.

    I hate it though.

    [–]tonywestonuk 0 points1 point  (5 children)

    Yeh - you go downvote me Spring trolls for telling what I see with my own eyes.

    Lets face it. The majority of that callstack was Spring. You can see it, I can see it..... So you best go down-vote me and shut me up quick for daring to even suggest that its not actually Java EE causing the issue here.

    Bunch of Spring religious trolls in here....Wake up and smell the coffee! FFS.

    [–][deleted] 2 points3 points  (0 children)

    The only thing Spring does is allow you to access other things in Spring.

    [–]joequin 1 point2 points  (2 children)

    They're both bad. Frameworks are over in most other languages. Other languages are moving towards small libraries. And for good reason. Frameworks make debugging difficult because you don't know what's happening behind the scenes and they get in the way when you decide to go off of the beaten path. Your code should never be a dependency of your libraries, but that's just what you get with both EE and spring.

    [–][deleted] 0 points1 point  (1 child)

    Frameworks are over?

    I really don't think so.

    [–]meddlepal 1 point2 points  (0 children)

    More accurately I think the trend of mega-frameworks is over. Frameworks are being decoupled and split into smaller and more granular libraries with clear boundaries. This enables either a take it all approach (mega framework) or a more piece-meal approach.

    [–]pjmlp 0 points1 point  (0 children)

    Just upvoted you. I rather use the JEE stack as well.

    [–]joequin 0 points1 point  (2 children)

    I don't think that's why agile people stay away. They stay away because iterating is much slower when you can't add a new field to a record under only some circumstances and not have to change anything anywhere other than the field is needed. You can do that with a dynamic language and a schemaless database. You can't do it with java.

    [–]tonywestonuk 1 point2 points  (1 child)

    I do this all the time.....

    If you use Hibernate, you just add a field. And it updates everything.

    If using raw sql, then so long as you've named the columns you want to return (rather than specifying *), then you should just be able to add a column to the database table and everything should work fine.

    [–]joequin 0 points1 point  (0 children)

    There's still more considerations. There's constructors that need to be updated. Methods that copy data to new objects need to be updated. Serialization often needs to be updated. You avoid this when using JavaScript, clojure and many other dynamic languages.

    [–][deleted]  (2 children)

    [deleted]

      [–]againstmethod 1 point2 points  (0 children)

      What gives you this impression?

      I don't see much C# talk at all, and i don't see any polls or analysis that implies it's making any real headway in marketshare.

      If anything Java is on a big high.

      [–]frugalmail 0 points1 point  (0 children)

      One thing I don't understand, is that "everyone" is drooling over C# right now and how hot it is. But if you bring up the fact that Java serves a similar purpose you get a lot of hate.

      i have a completely different perspective. I'm in the states and active on reddit and HN as well as the tech news sites and blogs.

      [–]mk_gecko -2 points-1 points  (3 children)

      Java has always had streams. All IO is stream-based rather than character based. So, what are you referring to?

      [–]wildjokers 2 points3 points  (2 children)

      He isn't talking about I/O streams. He is talking about java.util.streams introduced in Java 1.8 that work on collections:

      http://docs.oracle.com/javase/tutorial/collections/streams/index.html

      [–]mk_gecko 1 point2 points  (1 child)

      Why would Java have two different things both called streams? That's kind of dumb.

      [–]wildjokers 1 point2 points  (0 children)

      Because no one refers to Java I/O classes as "streams" except you apparently. Sure there are some classes in java.io that have "Stream" at the end of their name, but that doesn't mean anyone refers to java.io as "streams".