Live data from Hacker News

Data Classes for Java

cr.openjdk.java.net

71–80 of 216 posts

Re: Data Classes for Java

#71

... To write such a class responsibly, one has to write a lot of low-value, repetitive code: constructors, accessors ... If you're writing a plain data class, why on earth would you write getters and setters? Just make your fields public and be done with it. I will be forever perplexed by the idea of getters and setters (and this extends to C#s syntax sugar). I have no idea what problem they solve. If you're at the l…

If you have the option of a property later, there's no reason to start with accessor methods, but some languages don't support properties.

Re: Data Classes for Java

#72
post #32

Earlier quoted context omitted.

> Possibly more importantly, public fields give you no way to create immutable types. public readonly int Foo; readonly fields can only be set in the constructor, great for immutable types and with much better guarantees than protected/private/no setters.

This isn't true. For structs you can use 'this = ...' to overwrite yourself (including readonly fields) and reflection lets you set them too. fwiw those are both gross but I've run into both in production code (not written by me, naturally)

The same can be said for setters and getters with a backing field, you can access them through reflection. I can't remember how it works for properties with implicit backing fields but I thought they could be set via reflection as well?

Re: Data Classes for Java

#73

Earlier quoted context omitted.

This is a bit abstract to me. I don't tend to write mutable classes. And if I do mutate fields, it's for a "reason" (and I'll name the method after that reason). If you feel like it, write out how you'd implement the class and why. I posted a fairly strong opinion, but I'm happy to have my mind changed.

sure, ok, if you only write immutable classes, by definition you never need setters, right? i won't defend mutable classes (i won't decry them either), because i haven't personally thought tons about the benefits of immutability. i mean, i can see a lot of reasons why it's a good thing to shoot for, and i think it's a thing i often try to shoot for. but people often write mutable classes, or must maintain mutable cla…

If you have a mutable class, and you're modifying its fields, you're doing it for a reason, right? Often it's part of a larger operation. So why not name the method that mutates the field after that reason. I got away from thinking about "I am altering the internal representation of this struct + vtable" to "I am sending a message to this opaque thing and I don't really care how it's done when I'm outside the black box".

> but "setters are always bad and i don't understand why anyone would ever use them" seems like a needlessly hard-line sentiment, IMO.

I have a strong opinion because I read some compelling arguments, thought about a lot, stopped using setters, and the quality of my code improved. I don't see a need to moderate my opinions on programming, especially when that's what I really think. Again, happy to be shown a great counter example and admit I was wrong.

Re: Data Classes for Java

#74

Earlier quoted context omitted.

what if the constructor's not the only place you can set the value?

This is a bit abstract to me. I don't tend to write mutable classes. And if I do mutate fields, it's for a "reason" (and I'll name the method after that reason). If you feel like it, write out how you'd implement the class and why. I posted a fairly strong opinion, but I'm happy to have my mind changed.

Sure, for a simple class like this I would make it immutable too.

But the example is just a demonstration of the concept - you should be able to change the implementation without changing the exposed interface. When you first write a class, it may look like a simple bag of fields. But when that inevitably changes, getters and setters allow you to do it without breaking the clients.

Even if we keep this immutable, your implementation is different in that it uses twice as much memory. Maybe it's irrelevant, or maybe it's worth the tradeoff to use more memory and have faster access to the kelvin representation.

But maybe not. If you had getters and setters, you could seamlessly try the other implementation without changing all of the client code.

Re: Data Classes for Java

#75
post #18

Why underscores in "__data"? Is this just a temporary thing?

Java reserved words are reserved in all contexts. You can't have a variable called "class" because class is a reserved word. If 'data' becomes a reserved word, imagine the code that would no longer compile...

Re: Data Classes for Java

#76
post #30

Earlier quoted context omitted.

I like Swift's approach to this. (I'm sure other languages do it too, that's just the one I know that does this.) If you write a property (what other languages might call a "field") then by default it's a stored property, i.e. it's backed by a bit of memory in the object. If you need to take actions on changes, you can implement a willSet or didSet handler to do so. If you need to change how the value is stored and r…

I really, really dislike Swift's approach. get/set/willSet/didSet -- so much complication to preserve the illusion that you are operating on a field when you are actually doing no such thing. Why is this desirable? It reminds me of a class of C++ footguns where some innocuous code is actually invoking member functions due to operator overloading. I think that Java got this one right. (I do not at all like the cargo c…

Today's fields are tomorrow's computed properties. Fields are rigid and cannot be changed without recompiling dependencies. Notice how few fields there are in Java's standard library. Why have fields at all?

Re: Data Classes for Java

#77

... To write such a class responsibly, one has to write a lot of low-value, repetitive code: constructors, accessors ... If you're writing a plain data class, why on earth would you write getters and setters? Just make your fields public and be done with it. I will be forever perplexed by the idea of getters and setters (and this extends to C#s syntax sugar). I have no idea what problem they solve. If you're at the l…

Getters and setters are confusing because there are no reasons to use them for small projects, like what you would build in a college course. Software becomes exponentially confusing the larger it becomes. In addition, one piece of software may be built by multiple teams, such as using third party libraries. The best way to handle the additional complexity is to split each section into two: the interface (public) and the implementation (private). Here are the reasons why:

First, change. Changes to code happen all of the time. If someone wants to build a library so that many other users can interact with it, they have to realize that one day changes to that library will need to happen. If code is separated into public and private properly, then any private functions and fields can be rewired, and as long as the rewiring makes the public functions and fields perform the same, then the change will not break anything. How important is not breaking things? Well anyone familiar with Python's 2 and 3 schism knows the pain of changes that break compatibility.

Second, visibility. When you are interacting with a large codebase, you need to know what functions and fields to interact with. IDEs have very useful tools that can list these for you, but if everything is public then they will list everything. If 90% of your codebase is private data, that is a lot of useless functions and fields to sort through!

Third, hackery. When you are building a large codebase, there may be some things you don't want you programmers interacting with it to do. Users might take advantage of quirks in your code that were never meant to be used that way. XKCD's Spacebar Heating comic illustrates this nicely. Another reason may be security, as you might not want someone to have full access to functions and fields to poke around and understand your code better.

So these are the reasons why public and private are important concepts. The problem is then if something starts out as public, it won't have any of these advantages. If you want to change it to private later on, then you are screwed. So the Java solution is to make everything private from the beginning. Vanilla getters and setters are really just making private data appear public. Then if the data needs to be changed from "public" to private, the getters and setters can be modified accordingly.

Python's property approach is a similar concept, but infinitely better, as instead of relying on a programmer to build getters and setters, the language itself invisibly builds them under the hood. Then if you want to change something from public to private, instead of being screwed, you just add a property tag with the getter and setter code to change the getter and setter from an invisible default to a visible modification.

Re: Data Classes for Java

#78
post #9

... To write such a class responsibly, one has to write a lot of low-value, repetitive code: constructors, accessors ... If you're writing a plain data class, why on earth would you write getters and setters? Just make your fields public and be done with it. I will be forever perplexed by the idea of getters and setters (and this extends to C#s syntax sugar). I have no idea what problem they solve. If you're at the l…

You'll get you run out of town with that level of heresy in most java/c# shops. Getters and Setters are great when you want finer control over what can access certain fields, in a List class for instance, I wouldn't want the length to be externally writable. But somewhere along the way it went from a useful feature in some circumstances to a mandatory feature in all circumstances. In the c# world "public int Id;" wil…

I don't understand your complaint. The problem with getters and setters was the substantial tedious boilerplate required. C# completely does away with that to where there is no meaningful difference between the two in terms of typing required, while at the same time providing the benefit of encapsulation. So what's the problem? Do you really object to 14 more chars to type? That's absurd.

Re: Data Classes for Java

#79
post #38

Earlier quoted context omitted.

Sure, but every field access like Temperature temp = Temperature.fromCelsius(13); ... System.out.println(temp.celsius); would have to be changed to System.out.println(temp.getCelsius()); when the internal representation is changed.

I get what you're saying, but at the same time I don't understand how you'd implement the class and why. class Temperature { public final double celcius, kelvins; Temperature(int celcius, int kelvins) { this.celcius = celcius; this.kelvins = kelvins; } public static Temperature fromCelcius(int c) { return new Celcius(c, c - 273.15); } } What's wrong with that approach, and how would you do it?

Why would you have two separate temperature values?

Just have one in Kelvin that can't go below zero, and have getters and setters that translate to C/F when specified.

Re: Data Classes for Java

#80
post #37

Earlier quoted context omitted.

Not that nice compared to kotlin: data class Animal(dog: String, numberOfLegs: Int) val dog = Animal( name = "dog", numberOfLegs = 4 ) The amount of boilerplate for AutoValue builders is so ridiculous that most people use IDE plugins to generate it.

Very similar in C#: var dog = new Animal(){ name="dog", numberOfLegs=4 }; I use it all the time.

The big difference there would be, in the C# example you've still got to write a bunch more boilerplate for Equals(), GetHashCode() and ToString(). Kotlin's data classes give you those three for free.
Post reply on HN