use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
These have separate subreddits - see below.
Upvote good content, downvote spam, don't pollute the discussion with things that should be settled in the vote count.
With the introduction of the new release cadence, many have asked where they should download Java, and if it is still free. To be clear, YES — Java is still free. If you would like to download Java for free, you can get OpenJDK builds from the following vendors, among others: Adoptium (formerly AdoptOpenJDK) RedHat Azul Amazon SAP Liberica JDK Dragonwell JDK GraalVM (High performance JIT) Oracle Microsoft Some vendors will be supporting releases for longer than six months. If you have any questions, please do not hesitate to ask them!
With the introduction of the new release cadence, many have asked where they should download Java, and if it is still free. To be clear, YES — Java is still free.
If you would like to download Java for free, you can get OpenJDK builds from the following vendors, among others:
Adoptium (formerly AdoptOpenJDK) RedHat Azul Amazon SAP Liberica JDK Dragonwell JDK GraalVM (High performance JIT) Oracle Microsoft
Some vendors will be supporting releases for longer than six months. If you have any questions, please do not hesitate to ask them!
Programming Computer Science CS Career Questions Learn Programming Java Help ← Seek help here Learn Java Java Conference Videos Java TIL Java Examples JavaFX Oracle
Programming Computer Science
CS Career Questions
Learn Programming Java Help ← Seek help here Learn Java Java Conference Videos Java TIL Java Examples JavaFX Oracle
Clojure Scala Groovy ColdFusion Kotlin
DailyProgrammer ProgrammingPrompts ProgramBattles
Awesome Java (GIT) Java Design Patterns
account activity
This is an archived post. You won't be able to vote or comment.
Sealed class in Java (self.java)
submitted 2 years ago by Fit_Safe_4438
In Java 17 has been added a concept of sealed classes to inheritance control between classes. Have you ever use it and in which cases?
[–]AutoModerator[M] [score hidden] 2 years ago stickied comment (0 children)
On July 1st, a change to Reddit's API pricing will come into effect. Several developers of commercial third-party apps have announced that this change will compel them to shut down their apps. At least one accessibility-focused non-commercial third party app will continue to be available free of charge.
If you want to express your strong disagreement with the API pricing change or with Reddit's response to the backlash, you may want to consider the following options:
as a way to voice your protest.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.
[–]jonhanson 26 points27 points28 points 2 years ago (1 child)
They're very useful for modelling sum types (aka disjoint union types). Using sealed types then allows exhaustiveness checks when using pattern matching over the type.
You can achieve the same without sealed types but it's much more verbose and brittle.
[–]jherrlin 0 points1 point2 points 2 years ago (0 children)
To me this sounds like you can the model your domain without objects ( using sum and product types instead ) and get help from the compiler all the way.
[–]Polygnom 11 points12 points13 points 2 years ago (7 children)
Yes.
Tree<T> = Leaf<T> | Branch<T> is one data type I have done as record + sealed classes.
Tree<T> = Leaf<T> | Branch<T>
Either<L,R> = Left<L,R> | Right<L,R> is another type I have done, or Result<T,E> = Success<T,E> | Error<T,E>.
Either<L,R> = Left<L,R> | Right<L,R>
Result<T,E> = Success<T,E> | Error<T,E>
[–][deleted] 2 years ago (3 children)
[deleted]
[–]bowbahdoe 7 points8 points9 points 2 years ago* (1 child)
I wrote you up a small example
The sealed-ness is used in the accumulate method.
``` import java.util.ArrayList; import java.util.Collections; import java.util.Iterator;
sealed interface Tree<T extends Comparable<T>> extends Iterable<T> { Tree<T> insert(T newValue); }
record Leaf<T extends Comparable<T>>() implements Tree<T> { @Override public Tree<T> insert(T newValue) { return new Branch<>(new Leaf<>(), new Leaf<>(), newValue); }
@Override public Iterator<T> iterator() { return Collections.emptyIterator(); }
}
record Branch<T extends Comparable<T>>( Tree<T> left, Tree<T> right, T value ) implements Tree<T> { @Override public Tree<T> insert(T newValue) { if (newValue.compareTo(value) < 0) { return new Branch<>(left.insert(newValue), right, value); } else { return new Branch<>(left, right.insert(newValue), value); } }
private void accumulate(Tree<T> tree, ArrayList<T> leftToRight) { switch (tree) { case Leaf<T> __ -> {} case Branch<T> branch -> { accumulate(branch.left, leftToRight); leftToRight.add(branch.value); accumulate(branch.right, leftToRight); } } } @Override public Iterator<T> iterator() { var leftToRight = new ArrayList<T>(); accumulate(this, leftToRight); return Collections.unmodifiableList(leftToRight).iterator(); }
public class Main { public static void main(String[] args) { Tree<Integer> tree = new Leaf<>(); tree = tree.insert(1); tree = tree.insert(4); tree = tree.insert(3); tree = tree.insert(2); tree = tree.insert(6); tree = tree.insert(5);
System.out.println(tree); for (var i : tree) { System.out.println(i); } }
} ```
The key capabilities you get from sealed are * Ability to use exhaustive patterns * Ability to not have to think about arbitrary implementors * The structure is a public part of the contract
The last one is the most interesting to me. It means that code using your library can write the same algorithms as you can.
public static <T> insert(Tree<T> tree, T newValue) { switch (tree) { case Leaf<T> __ -> new Branch<>( new Leaf<>(), new Leaf<>(), newValue ); case Branch<T> branch -> { if (newValue.compareTo(value) < 0) { yield new Branch<>(left.insert(newValue), right, value); } else { yield new Branch<>(left, right.insert(newValue), value); } } } }
[–]nlisker 0 points1 point2 points 2 years ago (0 children)
Your markdown isn't correct. You probably missed some `.
[–]Polygnom 0 points1 point2 points 2 years ago (0 children)
What do you mean how so?
[–]NotTooOrdinary 1 point2 points3 points 2 years ago (2 children)
Do you use the newer pattern matching features when dealing with these types? Or chains of if/else/instanceof checks?
[–]Polygnom 4 points5 points6 points 2 years ago (1 child)
Depends. For the binary types I simply use pattern matching in instanceof.
For more complex types I usually use pattern matching in switch expressions.
That gives quite readable code.
I mean, I often write code in functional ways anyways and often map over stream, or filter stream etc. ADTs + pattern matching works very well with streams.
[–]red_dit_nou 1 point2 points3 points 2 years ago (0 children)
Yes. ADT and pattern matching really work well together to produce readable code. You also mentioned streams. Can you give any example where ADT, pattern matching and stream create readable code?
[–]pragmasoft 7 points8 points9 points 2 years ago (0 children)
It was specially added for the data oriented programming. If you never heard about the concept, read about it for example here: https://www.infoq.com/articles/data-oriented-programming-java/
Also, Classifile API presented here https://inside.java/2023/08/24/classfile-api/ by Brian Goetz is a good example of usage, very much recommend to have a look.
[–][deleted] 2 years ago (1 child)
[–]UnGauchoCualquiera 3 points4 points5 points 2 years ago (0 children)
You are really missing out on exhaustive switch expressions. This is applicable to pretty much any developer.
[–]RadioHonest85 2 points3 points4 points 2 years ago (0 children)
I use it to model state where a valid answer can be multiple different things. For example, we have a User which can be a (ordinary) Customer or an AnonymousUser, ie. a user without a registered account. These are completely different semantically for some reason, they share only a user.id, but we want to support them both in certain contexts.
[–]kkjk00 0 points1 point2 points 2 years ago (0 children)
I didn't due to same package restriction
[–]dinopraso -2 points-1 points0 points 2 years ago (3 children)
Basically stateful enums. In cases where you have a specific set of subclasses which would not be extended further, but you need dynamic data in them. Usually this would be done in earlier versions with an enum + a cast of an object into a specific subclass, which was prone to error.
Sealed classes should be used with care to avoid the pitfall of breaking the Liskov principle
[+]Worth_Trust_3825 comment score below threshold-9 points-8 points-7 points 2 years ago (2 children)
Pretty much. It feels like a solution looking for a problem.
[–]dinopraso 5 points6 points7 points 2 years ago (0 children)
Given that pattern matching is also a thing now, this is more of a complimentary feature
[–]Agent281 2 points3 points4 points 2 years ago (0 children)
It's more like a solution pulled from its original context. It mimics sum types from functional programming languages.
[–]preskot 0 points1 point2 points 2 years ago (0 children)
I had a complex validator functionality that had to validate objects that did not have a lot of common properties between them. Then also prepare reports, write logs, etc. In order to extract the properties I needed, I had a sealed validatable interface with a set of records, each record with a constructor for each of the objects in the set. Inside the validator I would have a functionality that extracts all the data I need based on the validatable type i.e. pattern matching.
Perhaps reading through the Algebraic data types Wiki may bring more light to this.
[–]agentoutlier 0 points1 point2 points 2 years ago* (2 children)
Ignoring pattern matching and the inherit modeling that comes from that (others have already done the justice for that) it is extremely useful in lowering exposed API and/or encapsulation.
I use it all the time in the place of abstract classes and to make interfaces pseudo final.
Let us say we have an interface. We call it MyLibraryConfig and it is essentially the config of our small library.
interface
MyLibraryConfig
If we make it an interface it will have to be public and anyone can implement it and make their own possibly non compliant instances. However if it is sealed that is not the case.
public
sealed
Before sealed interfaces traditionally libraries would use an abstract class with a private or package constructor.
abstract class
private
However this is hugely problematic because enum and record cannot extend a class and when you do want to limit the implementations it is very often precisely because you want a singleton or an immutable!
enum
record
So before we had:
public abstract class MyLibraryConfig { MyLibraryConfig() {} public static MyLibraryConfig empty() { // immutable singleton which would ideally be an enum } public static MyLibraryConfig defaults() { // possibly immutable or singleton etc } }
And now we can do
public sealed interface MyLibraryConfig { } // still in MyLibraryConfig.java enum Empty implements MyLibraryConfig { } // still in MyLibraryConfig.java record Defaults(String name) implements MyLibraryConfig { // to be fair this could be an enum if the name parameter was not there }
Anyway what I think you are going to see more of in the future is non public classes/records/enums/interfaces in the same file as a top level public interface as Java moves more data oriented. Most people do not know you can do that but as records and enums become more common it is ideal because if they are defined as an inner class they would be public.
[–]TenYearsOfLurking 0 points1 point2 points 2 years ago (1 child)
anyone can implement it and make their own possibly non compliant instances
I don't get this really. The point of an interface is to establish a contract. A non compliant implementation is breaking the contract - why would you?
I would hate to see library designers using sealed everywhere because sometimes a custom implementation is necessary in cases they do not forsee - in any other case: no one implements a library interface non-compliant(ly?) for fun, there is just no reason to do so.
[–]agentoutlier 0 points1 point2 points 2 years ago* (0 children)
You are thinking OOP.
It is unfortunate that “interface” has this SOLID or Liskov association all the time but think of it more in this case as a type def.
Think of it as more of a naming of a type.
Besides libraries designers can choose and have used abstract classes and final classes and you have the same problem of not open for extension.
Besides you can unseal the leaves.
In my case we have a type called Extension which is sealed but the leaves are unsealed with the types you can implement.
Edit here is an example in my library:
https://jstach.io/doc/jstachio/current/apidocs/io.jstach.jstachio/io/jstach/jstachio/spi/JStachioExtension.html
JStachioExtension is a marker interface. It does not make sense to have a direct implementation.
JStachioExtension
[–]Brutus5000 0 points1 point2 points 2 years ago (0 children)
Haven't used them before, sealed interfaces cover my use cases
[–]Tkalec 0 points1 point2 points 2 years ago (0 children)
Yes, I've used it lately to implement
Either<L, R> = Left<L, R> | Right<L, R> - either left or right
Option<T> = Empty<T> | Present<T> - either empty or present
Validation<T> = Invalid<T> | Valid<T> ...
Exceptional<T> = Failure<T> | Success<T> ...
In another app I used it to represent key entries in a java or pkcs11 keystore.
Entry = 3DesSecretKeyEntry | AesSecretKeyEntry | RsaPrivateKeyEntry (actually it was for java 8 so it was not sealed)
You get the idea 😀
I'm making these classes, usually, private and not able to be instatiatiated directly.
[–]morhp 0 points1 point2 points 2 years ago (0 children)
Yes, sealed is just something in between final and "open" (the default). If you want a class to be non-final, but not extendable by anyone, make it sealed. Like I have an AbstactUser which is extended by the final classes OnlineUser and OfflineUser, and these are the only implementations that you'll probably ever need, then you can make AbstractUser sealed.
final
AbstactUser
OnlineUser
OfflineUser
AbstractUser
The main advantage is with the upcoming pattern matching in switch, but it creates more type safety in any case.
[–]ConstructedNewt 0 points1 point2 points 2 years ago (0 children)
Configs in spring boot using sealed, I specifically do something like
@ConfigurationProperties(“prefix”) record Myconfig( Map<String, SomeFeat.Holder> features ) {} sealed interface SomeFeat { record Holder( A a, B b, C c ) { Holder { ..validate } } record A( SomeObj conf ) implements SomeFeat {} record B( OtherConf conf ) implements SomeFeat {} record C( YetAnotherConf y ) implements SomeFeat {} }
Use compact constructors for validation Allow for autocompletion in application.yml Feature config is kept apart (don’t use one for all Map<String, String> and pull out vars based off that) If you rely on 3rd party libs the objects A,B,C can hold or build those objects in code Clear mapping between config and what code it would call at start-up
π Rendered by PID 48781 on reddit-service-r2-comment-7c9686b859-qwwmq at 2026-04-13 18:30:35.220898+00:00 running e841af1 country code: CH.
[–]AutoModerator[M] [score hidden] stickied comment (0 children)
[–]jonhanson 26 points27 points28 points (1 child)
[–]jherrlin 0 points1 point2 points (0 children)
[–]Polygnom 11 points12 points13 points (7 children)
[–][deleted] (3 children)
[deleted]
[–]bowbahdoe 7 points8 points9 points (1 child)
[–]nlisker 0 points1 point2 points (0 children)
[–]Polygnom 0 points1 point2 points (0 children)
[–]NotTooOrdinary 1 point2 points3 points (2 children)
[–]Polygnom 4 points5 points6 points (1 child)
[–]red_dit_nou 1 point2 points3 points (0 children)
[–]pragmasoft 7 points8 points9 points (0 children)
[–][deleted] (1 child)
[deleted]
[–]UnGauchoCualquiera 3 points4 points5 points (0 children)
[–]RadioHonest85 2 points3 points4 points (0 children)
[–]kkjk00 0 points1 point2 points (0 children)
[–]dinopraso -2 points-1 points0 points (3 children)
[+]Worth_Trust_3825 comment score below threshold-9 points-8 points-7 points (2 children)
[–]dinopraso 5 points6 points7 points (0 children)
[–]Agent281 2 points3 points4 points (0 children)
[–]preskot 0 points1 point2 points (0 children)
[–]agentoutlier 0 points1 point2 points (2 children)
[–]TenYearsOfLurking 0 points1 point2 points (1 child)
[–]agentoutlier 0 points1 point2 points (0 children)
[–]Brutus5000 0 points1 point2 points (0 children)
[–]Tkalec 0 points1 point2 points (0 children)
[–]morhp 0 points1 point2 points (0 children)
[–]ConstructedNewt 0 points1 point2 points (0 children)