Live data from Hacker News

Better Java – Resources for Writing Modern Java

github.com

101–110 of 192 posts

Re: Better Java – Resources for Writing Modern Java

#101

Re the first bit about 'struct' style, even better (IMO) is to use Lombok; throw an @Data annotation on your class and all you need to do is put your properties in there (private final if need be). Nobody should be writing those boilerplate constructors, getters and setters. If it's generated by your IDE, use Lombok. The best code is no code.

then you suddenly force anyone who uses your code to depend on lombok. I tried to find a compile time only mechanism for lombok - not sure i found it, but it ought to exist!

Re: Better Java – Resources for Writing Modern Java

#102
post #98
post #3

"If you're using Java 8, you can use the excellent new Optional type. If a value may or may not be present, wrap it in an Optional class like this" While I agree with most things, overuse of Optional like this is an antipattern IMO. Having done a lot of Java 8 development, I find Optional is best for return types, but otherwise forcing callers to wrap values in Optional is unnecessary as opposed to something like Sca…

When I get some time I'll update the OGMJ. I think the choice of tools mentioned is still very much up-to-date, it's just that some of the APIs used in the examples have been upgraded.

I really like OGMJ, it's definitely a great resource and I recommend it to many new Java developers; however, I disagree re: tools mentioned.

After trying dropwizard for a few projects, the superiority of the spring-boot and its various ecosystems just blew me away.

Also, while I appreciated Gradle, Maven is just much more supported through the entire eco-system. As a new comer to Java from C++/Python, it made a big difference.

Re: Better Java – Resources for Writing Modern Java

#103
My solution is to use Groovy wherever possible. It has a superb syntax, very low learning curve and compiles into JVM bytecode. There is no issue with getters and setters in Groovy - you just define the fields, which Groovy calls properties and defines implicit getters and setters.

If not for the main application code, I would definitely use Groovy for unit testing in combination with Spock Framework. You just have to try it once to realise what you've been missing all these years with JUnit.

Re: Better Java – Resources for Writing Modern Java

#104
post #75
post #2

Streams are questionable in performance vs non-stream approaches. I haven't found an article that details performance differences, but I will say that I personally tried doing things using streams and doing the same things using non-streams and have had mixed results, one being faster than the other in some cases.

The benefits of streams isn't performance improvements for the CPU, but performance improvements for the developer.

i have colleges that claim streams don't necesserily make the code more readable. Imagine a triple nested for-loop - making it a triple nested streams (e.g., where your map method is yet another stream), doesn't seem to really make it any more readable.

The only reason to use streams, i think is the possibility to automatically parrelize, and secondarily to make it more readable.

Re: Better Java – Resources for Writing Modern Java

#105

Some good suggestions in here and some very very bad ones. For example, using Optional as a member type, tuples etc.

this details a good amount of the problems with optional, but yet why it will still be used despite it: https://developer.atlassian.com/blog/2015/08/optional-broken...

Re: Better Java – Resources for Writing Modern Java

#106

Earlier quoted context omitted.

Another problem with struct approach is inconsistency. Sometimes you want a computed property and you use non-trivial getter. Sometimes you want to do some work in setter. And then client's code will look terrible: point.x * point.x + point.getY() * point.getY(). There are other problems: binary incompatibility; non-trivial refactoring when I need to introduce a getter or setter. Java really need lightweight property…

Going from C# to Java, one of the biggest things I miss is the Property syntax.

C# property shares its own set of issues , especially when there are exceptions involved.

Re: Better Java – Resources for Writing Modern Java

#107
post #73

Earlier quoted context omitted.

Can you expand on the later point about final please?

tl;dr: final parameters != immutable and safety, and they look like they ought to. A lot of people write "final" in front of every. single. declaration. And they do that because someone once told them that was good. But then you remember that Java is a language which all non-primitive types are passed by reference, so your 'final' is actually a final reference and not a const immutable object, like you might get in C…

i wish java had designed final to be semantically const just like C++ (but without the type level breakages that seems to happen in C++).

Re: Better Java – Resources for Writing Modern Java

#108
As a fan of immutable objects, I bemoan the builder pattern. The nice thing about constructors (or factory methods) is that you have a compile time guarantee that you have all required components to construct an object and validate its invariants. With a field oriented builder, only the documentation informs you whether you've met all of the conditions to construct an object. Also, a builder which mutates its own internal state breaks the idea of partial application where several variants can be constructed from a parent.

Unrelated to builders, the stream example could be simplified further with method references

    final List filtered = list.stream()
        .filter(s -> s.startsWith("s"))
        .map(String::toUpperCase)
        .collect(Collectors.toList());
It would be nice if Oracle back filled some predicates to make them more useful in streams (e.g. "s"::isPrefixOf, etc.).

Re: Better Java – Resources for Writing Modern Java

#109
post #79

Earlier quoted context omitted.

Despite what he says, I don't think Hoare actually invented the "null pointer", as address 0 for "not exists" or "end of list" was probably a common convention ever since linked structures existed and independently discovered by many others. (The other convention would be the all-bits-1 value, but I'd assume that testing for 0 was easier and thus more widely adopted. Also, "0 = nothing" makes great sense.) IMHO Optio…

Yeah, Optionals came from other languages, not originally Java. IMO the problem with Optionals is that they'll never suffice unless they are part of the language itself, like in Swift. As this article pointed out, Optionals aren't supported in any existing APIs, so you still have to do a ton of null-checking everywhere. And there is nothing that guarantees an Optional reference itself can't be null, which is why you…

I'm probably being a bit too pedantic here, but strictly speaking they don't need to be part of the language at all. You just need basic support for (generic/parametric) algebraic data types.

For example, Haskell has Maybe which is not part of the language nor treated specially by the compiler in any way. It is part of the Prelude (think "standard library"), so that (basically) all libraries can agree on what "Maybe a" means.

Re: Better Java – Resources for Writing Modern Java

#110
post #74
post #64

I used to be a fan of the Builder pattern (or Fluent Interface), but the ease of use for developers comes at the cost of no compile-time checking. Before, you just had to look up the constructor to see which parameters go where, with the benefit of type-checking. Now, you have to look up the Builder's methods to make sure you've filled in all required fields. The only case where I can actually advocate using Builders…

If you have this problem, the library you're using is incorrectly using the Builder pattern. All required parameters should be in the constructor of the builder. Then the other methods on the builder should be optional configuration. For instance on Android you often see a builder that takes a `Context` in the constructor because that's almost always required.

This is contrary to the OP's example, where he passes data and num to the constructor, which is how I've seen it used frequently. The Builder pattern is often recommended to "make code easier to read" and wouldn't be useful if many/most of those parameters were required.
Post reply on HN