I worked at Google, everything was Java 8. I worked at Amazon... hell i worked on some stuff that was still Java 7. Both of those teams worked on core services. Java is proof that the syntactic sugar that devs get hyped about means very little, the value of a language is in its stability over the long haul
It just means they locked certain libs for specific versions since java does all it can to be backwards compatible Syntactic sugar it usually ment to reduce the amount of code you write to make it more readable and faster to write while doing the same thing under the hood when the code is compiled
I feel you. I just quit a job, because they still used java.util.Calendar all over the place. And they were so proud they just recently switched to Java 8. It’s just embarrassing when you know what modern Java actually looks and feels like.
That's what i don't get it, the very things the people use like TH-cam are written mostly in java but everyone says that is old, bad and no one is using it.
That's the whole point of Java, slow and steady and the reason why enterprise loves it so much. Ecosystem built on top of it solves all the business problems. You dont have to relearn 30% of language each year just because hot and popular languages like to bloat themselves with each new release. Constant changes and features != stability.
Its right most of the companies stay with what they have and Java is a nice enterprise language. Javas problem besides the license stuff from Oracle. Is the whole framework madness for lack of better words. They built frameworks on top of frameworks on top of frameworks. Mostly all of things settled on Spring Boots which is also just a meta framework. There a 3 reasons why this is so bad . 1 You have the broken virtual class problem finding the bug is super hard and can be caused by anyone in the chain who updated his product which also result in a very slow update process. 2. Java is the programming language with the most dependency injection vectors including this . other are Maven or now worse Gradle 3. Back then those people who could handel this were called JEE devs and made 30% to 50% more then the other devs which is a negativ for a company.
@@Fiercesoulking Can we please agree to stop using the word "meta-framework"? It's completely meaningless. Also, "Dependency injection vectors"? "Maven or now worse Gradle"?
@@Fiercesoulkingyou talking tottally bullshit about spring boot ecosystem. I Working java developer several years and i never met with problem in you comments. Even i use java 17+ versions every day. Java frameworks are awesome and there is no programming languages which has even close to spring boot (mb c#, but it also java).
honestly, I think most people when they think of java, they think about how they feel while using it, but truth being told, I think for an enterprise, java is one of the best languages out there. It's stable, it has tons of support, it generally is less verbose than people make it to be and most importantly, it's quite consistent on how you can resolve an issue. If you open 50 classes, 80-90% of them look exactly the same. If I get a node express server for instance, I'm pretty sure that on 10 projects I'll have 15 different implementations (which is not bad per se, but if you need to switch out the people who work on it somewhat regularly that's bad)
@@LiveErrors java pretty much has everything you need and want as of today honestly. Also, most of the stuff in the video is in the langiage since 3 years, also, metaprogramming is best out there pretty much.
Java being the oddball trying to fit in with the cool kids, except now that 30 years have passed it just gives off Steve Buscemi "how do you do fellow kids" vibes
they're basically sealed classes in kotlin, but they're interfaces so more applicable. but at the same time, kotlin can autocast stuff for you, and its when expression doesn't need a subject, so it has no need for its sealed keyword to be applicable to interfaces, where it barely even makes sense. also java already has enum classes, which are a tagged union, which are a more concise version of this, as far as i can tell.
Yup. Sealed class hierarchy instead of a tagged union type. The use cases are the same as rust enums when you need a limited, limited set of shapes with some compiler help around completeness at usage sites. They just made it awkward as by having the interface have to forward declare its children. Probably so they can put it into the byte-code and enforce it at runtime. AFAIK each class compiled to a seperate loadable unit. Each is essentially an island in the JVM.
@@Bliss467Kotlin has sealed interfaces, and they're a lot lot nicer. Remember that you can only inherit from one class, but from multiple interfaces, and that carries over to multiple sealed interfaces
Five months later I am watching this again now. Discriminated unions are currently a really high requested feature by many people in C# too. I guess chances are pretty large that a similar approach to this will be done for C# as well. Simply limit your inheritance options, so that you can do exhaustive pattern matting. Voila. This also matches with F# quite well which is compiled into a set of classes in a similar fashion. And this matters if people want both dotnet languages be able to work together very well. This approach has probably also the least interference with existing design patterns in OOP style languages. But silently I like actual Rust style enums more, which are more concise. Sometimes conciseness is not the only consideration however, so you have to fall back to existing language elements and improve those instead.
ปีที่แล้ว +132
Virtual threads remove the "color" of the functions, the same function could be blocking or not depending on where it runs, and that is amazing. There are no "async", "suspend", "callbacks" ...
Fair enough but you are missing the point of Loom. They didn't just implement green threads, they did it while keeping compatibility with the language's existing Thread/Concurrency/blocking APIs. That's a significant achievement IMO.
Some of the examples given here are quite bad in my opinion ^^ 1:04 You don't need to use stripLeading() with text blocks, leading spaces are already stripped by the compiler. 2:41 They only put one field in the first record example, a better example would be `record Person(String name, LocalDate birthday) {}`. 12:46 I don't know why they've put a separate instanceof above the switch... 20:39 You don't need to nest try-with-resource statements, you can declare multiple resources inside the parentheses.
In general I agree, but still they could (and should) improve the syntax. Having some kind of async await that automatically uses virtual threads could make it a serious nobrainer. Don’t get me wrong: I really love the feature with all its possibilities. I just wish there was some really simple stupid syntactic sugar (I call it the SSSS principle) for the most common use cases.
Really? How is it better than coroutines in dozens of other languages? My prediction: it's a good feature for teams already using the JVM, but it won't move the needle on performance benchmarks enough to convince anyone using Go or Rust to switch.
@@mikeswierczek Who said about convincing anyone using Go or Rust to switch? I never said that, I said "the whole point of virtual threads is to get the performance of async await with regular, blocking like APIs". Do you agree that the async/await syntax vs lack of constitutes an important semantic difference or not?
@@petrzurek5713 well, there is an interesting development Oracle sells support plans. If the company don't upgrade then they have to pay Oracle for support. If they don't pay Oracle for support and they operate in EU then when they are hacked and during the hack there is leak personal information, EU can impose penalties up to 4% of last year profits If ain't broke don't fix it doesn't work any more
No doubt you are a good programmer. However, it seems your attitude in analyzing Java 21 is not that serious and very biased since before reading the article. And to be honest, although you had used Java for sometime, I don't think you know Java so well now. I started with C & C++, and then switched to Java since JDK 1.4.1. In recent few years, I learnt Go, JavaScript, TypeScript, and Rust. Well, Rust is a very powerful programming language with a lot of good new concepts. However, for my new server-side e-Commerce Big Data Analysis project, I still chose Java because I consider it the best choice after comparing with all the other languages I mentioned above. If my project is an Operating System, a Real-time System, or a hardware related application, then, I will probably choose Rust. Even though Java code is a bit longer than Go or Rust with boilerplates, in my point of view, it's the easiest to read and manage language for large-scale enterprice application development among members of a big team. With modern IDEs (e.g. IntelliJ IDEA), a longer code with boilerplates does not cause longer time to write at all. In your video, you hardly spent any time in analyzing the Virtual Threads (and did not cover Structured Concurrency at all), which for me are the most attractive 2 features in Java 21.
I've been developing in C and C++ for 30 years. Trying to learn java for the past decade and getting nowhere with it is blowing my mind in a very bad way. It sucks.
Exactly. What's up with this guy? This is the first video of this channel that I'm watching and I stopped after a few minutes to scroll the comments. This video feels so unprofessional as he scrolls the article and reacts like a kid. Be humble
Sealed interfaces are really useful for cases where e.g. you are creating a library with a bunch of types that you do not want to expose to the user (e.g. just for the sake of simplifying the library's interface for users). So, you can expose an interface instead which your 'internal' types implement. But, your library might still be dependent on the specific implementations to behave a certain way, and there is no way to restrict the interface to force implementers to honor the contract (simple example: a method should always return a positive int). In other words: This interface is not meant to be implemented by random users. To show that the interface is not intended to be implemented, and to prevent weird issues where a user implements the interface but does something crazy which breaks your library code, you can make the interface sealed and only permit your library's own types to implement it. The bi-directional dependency might seem weird, but sealed types are really only meant to be used within a unit of control. e.g. a module/package or within a class (for nested classes the 'permits' clause is not even required)
sealed interfaces really work well for ADTs (Algebraic Data Types) as well as messaging interfaces, where you want to have a determined (closed) protocol of message types.
Yeah, it's basically the same as ADTs, but it's perhaps the clunkiest way they could have gone about it. Why not borrow from Rust or Swift and just have enums with associated values? It's a much cleaner, clearer way of writing an ADT.
Java's slower pace at adopting some things is kind of a benefit tbh. It can sit back, wait until something catches on, then add it while remaining stable & consistent. You don't want to add something to Java only to have it fall out of favor in a year because then you end up either having to maintain support for this thing almost no one is using (creating more opportunity for bugs, vulnerabilities, etc...) or you end up breaking a bunch of stuff when you deprecate it and rip it out of the language.
As prime said java has been around for decades ,used by large organizations and being rock solid stable , so hearing people hapring about "oh this was on this languae for years" is getting pretty dull, the size of organizations here won't be impressed with syntax sugar here or there as long as the thing runs and works.
The sealed classes are basically the equivalent to tagged unions; you would use them like you would use enums in Rust. Since this isn't really OOP, it feels out of place in java, but I honestly really enjoy it whenever I'm forced to use Java. Integer divides can overflow: A signed byte is between -128 and +127 (inclusive). Therefore, dividing -128 by -1 results in an overflow.
I for example use it for my kafka consumers: A sealed interface KafkaMessage with a "type()" getter and other common message property getters, bunch of records implementing it inside, with different properties (the permits is implicit in this case since the records are declared inside), and smart deserialization based on type's value (with Jackson's @JsonSubTypes). Then I can have my handler receive KafkaMessages directly and switch on it with pattern matching (was already available in java 17 behind a flag) or not, and even switch on it later for other operations. It could have just been OOP instead (basically a KafkaMessage::handle method to override, instead of sealed+switch), it's just nice to have the option to have basically an enumeration of implementations that i can easily switch on safely, and it's sometimes a better approach, like if you have multiple operations depending on the implementation with common behaviour for some types depending on the operations and don't want to end up in an overkill OOP pattern to DRY that a junior dev (or you in two months) will take 2 days to understand: just switch on it instead when you need to, directly in your "main" logic code, imperative or functional. It's part of the effort to have less OOP and more functional code since java 8 and I like it. Well it's basically Java catching up to Kotlin, which is still the best jvm language IMO.
The nested trys at 21:30 aren't necessary. A try-with-resources block can handle multiple resources. Also try-with-resources isn't remotely new, it's been there since Java 7. The first part of the article that mentioned it was just about the HttpClient class implementing it, which is weird because that came out in Java 11.
20y working with Java, I'm having a affair with go now. I could say that java 11 is enough for the 99% of cases and i love it. Yes, I said java 11. Just write good code, don't blame the language.
Most of the problems with Java are the over complications Enterprisey devs create. We have a huge big data processing app in Java and I don't think we have s single Factory, let alone a Factory Factory, or a Java doc that contains nothing but 500 class definitions and no comments.
While this says "Java 21" this is actually a list of a bunch of features that have been added between Java 8 (the last LTS version most people were using) and Java 21 (the at the time of writing newest version)
@@gontsaru Well, the only current LTS versions is 11. Extended support for 17 and 21 ends before that for 11 ends ... One should NOT buy the LTS moniker as Oracle uses it. Support for 17 even ends before 8! There would be more enterprises adopting a newer version than 8 or 11 if Oracle would actually commit to it ...
Java's ubiquity and speed, especially compared to other garbage-collected languages, make it noteworthy. Go (Golang) is the only other garbage-collected language that rivals Java's pace. Modern Java, with features like Virtual Threads and GraalVM for native executables, is impressively cool. Embrace different languages based on their merits and fit for your specific use case. Stay language-agnostic and choose what solves your problem effectively.
Even though it started as a ripoff of Java, C# is today way ahead of it in nearly every aspect and its iteration cycles are significantly faster. So yeah I don't buy into your Java and Go exceptionalism. There are plenty other languages.
@@Y-JA Fair, but microsoft really shit the bed with C# and .NET. Making it tightly coupled to the windows and microsoft ecosystem was a mistake. Many corps can't make such a big commitment, nor do they want to spend the exorbitant amount of money. Because its all one big package... you're not just purchasing .NET, you're purchasing dozens of things. Things are changing now - but too little too late. .NET was never an option for those who use Linux backends, and due to the historical momentum it'll stay that way.
@@theshermantanker7043and people keep saying that java "catchs up" but it's more that they add things when they make sense. Java 22+ plans to integrate LINQ while C# tries now to copy java virtual threads. Which make as of today, java way more scalable then C# for concurrent app. I find it really impressive to be able to spawn 10M virtual threads that has solved the issue of context switching.
Im a learner learning java atm and while I too dislike java, I feel like my skills in java has grown quite a lot over the years. I cant tell whether its writing in java that's fun or if I just love Object Orientated Programming, but right now I'm glad java is evolving as I'm still learning it_
I can relate to your experience. Java was the first language I learned in depth at College. I enjoyed it a lot which I didn’t expect considering all of the hatred for the language. But now that I’ve learned a bit of C#, I see that what I enjoyed with Java was the OOP paradigm and not really the language itself. C#, to me, is essentially all the things I liked about Java without all the things I didn’t like
Java is a very thin layer of abstraction over its OOP. It's hard to have any opinion at all on Java without it actually being an opinion on its approach to OOP. You like the OOP.
@@Ellefsen97 kind of agree, my problem with C# was Microsoft , then Oracle acquired Java and I stop caring , after I discovered CoreNet, I still program in Java or Python, or JS depending the project
@@Lemmy4555 The JVM is far more than for just supporting multiple platforms. You get a runtime that supports multiple languages, excellent JIT compiler, excellent GCs (far better than golang's), second to none introspection and observability capability, etc.
Tip: JVM languages like Scala, Kotlin, Groovy etc are experiments. The best parts from these languages are absorbed into Java after being battle tested and found useful for years. This curation process is why Java seems to move slow but it really helps keep the core clean. Scala was hot a decade ago now it's Kotlin. Google is pushing Kotlin for Android as it does not want Oracle to sue it in future. Don't get swayed so easily, there is value in a stable language.
@@zhamed9587 that's true, they don't have to reinvent the wheel everytime, but some of these takes are mitigated or fully handled by using LLVM like Rust and Julia does.
The point of sealed interfaces is algebraic data types. Imagine a Result type or an Option type. The idea that "you have to come up here and modify it when you add new things" is nonsense because it isn't really an "interface". You aren't modifying it pretty much ever. You are creating one type with specific implementations
Records as well, which the product types. Minor nitpic, sorry. But my impression is that many people explain it incorrectly. The term ADT is the general term for both product types and sum types. These sealed interfaces are the sum types. Most functional programming languages call them tagged unions or discriminated unions. Some languages, such as Rust, call them enums.
You guys are vastly underestimating the coolness of virtual threads. This gives us the efficiency of async/await without the complexity. With async/await, you have to say something like, "tell B to call C when B is done, tell A to call B when A is done". In java, you can just say "do A, then do B, then do C", and get the same performance.
@@lufenmartofilia5804 Right! It is much better than async/await because code execution is a straight line; no promises no "then" methods. To be fair, though, per-virtual-thread ram usage is not zero, but neither is node.js async/await.
The whole point of async/await is to avoid the nightmare of nested code. Java's virtual threads do not even try to address this code readability issue that has been plaguing the language from the start.
@@RandomHandle120 Virtual threads is a 100% solution for the code readability problem of async/await. All you have to do is write old-fashioned blocking code, the way we did before async/await existed, and then under the hood it does the equivalent of async/await.
The reason that switch pattern matching requires sealed interfaces (with permits) is because it's not always possible to know, at compile time, how many possible implementations of the interface will exist. Switch expressions must be exhaustive. For example, if you are the author of a library that switches on an interface object, allowing consumers of the library to implement the interface may cause issues with the already compiled switch expression.
I still love java. I've worked professionally with python, objective-c, swift, java-jr^H^Hscript and others and nothing beats the stability and maintainability of Java. it just beats everything. commence flamewars.
For the sealed types, it's basically exactly the same as Rust enums. Instead of improving the current java enums (they tried and failed), they instead modified the interfaces.
rust misusing the term enums because they didn't dare use sum types is honestly really annoying. There is an almost complete disconnect between what everyone else means with enum and what rust means, and honestly, everyone else is correct.
They're handcuffed by backwards compartibility. So it's either come up with a new synax for data types or double down on records (I hate permits idea btw).
There was actually a method to it, there were 8 spaces for a line continuation and 4 spaces for a new scope. Their paren spacing sucks though, all-around ew.
Sealed types allow you to code for them, externally, as a single thing, and make them publicly available, while also restricting external users from creating - and passing in- their own implementations. Basically, it's "nice" to have enum types that can also do things normal classes can do (like inheritance) and use that internally in SDKs, libraries and frameworks. It also gives you a way to scan the class hierarchy downwards without scanning or anything of the sort, which is great for implementing enums that must have different typing but e.g. unique key values within a given context, which you can then easily check at startup/unit tests.
10:45 You missed the whole idea of this. Java still has so-called open interfaces (those that you all know); they added the sealed ones to give devs a new thing in design space: It allows exhaustive switch statements; it’s a lot like enum conceptually, except that enums only has fixed objects . When you add another Animal, you want to update the switch statements. You have to update the _Animal_ interface so the switch notices that something is missing.
The worst part is that enterprises will not update their java version. Meaning this is good for at most 5 devs who managed to update java without their 20 QA noticing after 3 months of review.
Enterprises care more about stability than your opinion. People complain about lack of features. Java implements some good features albeit late and inspired by other languages. People still complain . It promotes new software to potentially use those new fancy features. It's LTS. Java is to enterprise backend what C is to systems programming. Don't understand what you're waffling about. You can still continue to not use what you don't want 😂.
This is uplifting, I will likely switch team and I will be using Java 21. I hope is actually better than the Java 8 I left. Tired of TS/JS on big projects. It has become as tiring as Java. Unfortunately in EU Go is still not as used, especially in my country.
It will be better, mate. It's almost a decade since java 8 release, there are lots of improvements in the jvm internals, new garbage collectors, higher pace of introducing quality of life changes
You Will enjoy it, writing code in java 8 and Java 21 (using the new features) it's almost as writing in 2 totally different languages. Writing in java 21 feels almost like coding in JS but without the totally idiotic and detach from reality implicit casting Javascript does with types in order to call itself "dynamic" and without the spaghetti code they get with the super nested functions and callbacks.
I love programming in general and because it's my first language i love Java. Especially because of new release train, and new(for Java) cool(for Java) features
For states in a Future, I've had to look at it at a low level while mocking asynchronous message handling in a unit test, but it was with Java 11 so it was messy to write!
Have to love that java gets new versions, now if only companies would use them 🤣 Also i like how oracle made java less verbose in some things but give you extra tools to add more abstraction and verbosity
Loom wasnt shown off properly but basically its the same as async/await javascript/rust but without having to put async/await. Some internal differences ofc with Rust still being more efficient, but thats the idea of loom.
it would be cool to see you digging deeper on why other languages already have something in terms of performance for what virtual threads are bringing to the java world. buuuut, the real thing that the java community is excited about that this article did not mention is that it will let devs write java code in a blocking style, with the benefits of non-blocking to reduce having to deal with futures, completable futures, reactive programming and all the good stuff that drive every java dev nuts when we need to do parallelism. I wonder if any language allow that? without having to do something similar to async/await everywhere
you can see prime absolutely hated reading this article because it was about java even though these changes make it pretty much a different language at this point. i wonder if a rebrand would fix anything...
Sealed types are actually quite beneficial. You control exactly who can implement it therefore you can have a library expose an interface that where it is used can't have certain things be implemented potentially incorrectly. The exhsustiveness is also another benefit. But the way that Java does it is really really bad. The declaration of the inheritance should not need to know about every instance. Kotlin has had them for quite some time (if not since the beginning) and they simply must be defined in the same package in the same module, the definition of the interface doesn't need to permit the implementations.
@@iceinvein This was my point, not too many ppl do that. I have to add, that new java has string template that is better than simple string interpolation.
The reason for sealed classes is this: often a library will expose an interface, and static factories to create instances. we do not want the customer to be creating those instances. This mechanism allows that.
hating on java is just a cringe meme that is self-perpetuating. who gives a crap about syntactic sugar? it's nice but it certainly doesn't outweigh the ecosystem which is Java's strong point.
I work in java. Java is cool, I like it. The thing I don't like is Java developers who have java 17 on the board and still are not familiar with features from java8. Optionals - who needs it? Streams, lambdas - meh straightforward loops and chrismas trees in the code are best. Records? Nah - it's better to use lombok and generate some code under the hood.
@@metaltyphoon They dropped the 1.x numbering starting with Java 9. Which broke programs that looked at only at the minor version. Then Java 10 broke programs that compared versions as strings. Also, more confusingly, "Java 2" refers to any Java between 1.2 and 1.5.
even in rust I find that sealed trait is a very common pattern even with enum type available. But that’s only for access control and cannot do what Java provides with exhaustiveness check on sealed interface. Enum in rust is data, and two enum types cannot be paired to form a description on a same piece of data, unlike traits. But traits are weak and don’t provide exhaustiveness semantics. As a guess, to have the same power, it seems to require a proper sum type with intersection operation?
It’s also a really simple language. There isn’t much special syntax. 99% of the code you read does exactly what it looks like. I don’t have to think when looking at other peoples Java code. That’s what I really love about it (and of course the huge ecosystem). It’s really hard to f*ck up Java code. I consider this a feature.
@@benm1295yeah just create a factory to create a class that creates another class that has dependency injection so that we can get the other factory and then sum up two values :) does everything expected 🤦🏻♂️
Sealed interfaces (another thing stolen from Kotlin) are useful in certain contexts. It's not about "we don't know who's going to implement it", rather it's about "We want to control the implementations, but we don't know which of those impls someone is going to pass via LSP"
Java: When humans cannot understand something, they become hostile towards it. Do not be upset by their attacks, fear their lack of understanding. My power lies in the peace and mental security that I provide to my lovers, not in creating controversy and making noise.
as a java dev of 22 years....im not sure i like sealed interfaces yet either...what would you do if you want to expose an interface for third party use..? they cant use it if sealed...perhaps there are limited ocassions i could see it being of benefit.. The nice thing is you dont have to use them :) Records are kind of where things were trending with lombok for years anyways ...
Yeah but with records you don't need Lombok anymore, at least no for DTO classes. The less plugins and dependencies you use to get some syntax sugar, the better.
@davidgrajalesmirage definitely...I didn't mean it wasn't a good thing to have it builtin..just saying this is the normal flow...just like how we used to use joda time but now it's part of the Lang
@@shykial_ they are types yes but not really used as values. A functions signature in Kotlin doesn't tell you that it could go wrong, neither what could go wrong. In that sense, even Java is better then Kotlin. Another alternative are result types like you see in Rust which is referred to as "errors as values" afaik.
@@jamesgibson1893Yeah Kotlins DSL can be really strong if used in the right places. What's the Problem with Gradle though? (I originally came from maven, npm and pip (absolute nightmare) so my standards might be too low)
@@floppypaste you can always use @Throws annotation to indicate function may throw some exception, but if exception is one common outcome of a function which you would like to enforce handling straight away than why not use Result type or something else like Arrow's Either type? I personally am not a fan of Java's checked Exceptions and to me using Result/Either makes much more sense when you would like the caller to handle exception case directly
If I want to love Java, I’ll use Kotlin. Get the benefit of the JVM and JDK, but Kotlin is so nice in comparison. Both are still second fiddle to C#, though
@@Tvde1I mean, it does have some benefits in that it's runnable pretty much everywhere and there is a massive library ecosystem for it. Would I personally use it? Not really, but I can't deny it its good points
I really like Java for sheer stability. Decade old projects still supported and can be build for older machines or JRE. Even Swing apps now adapting to HiDPI. But I dislike Spring. It introduce too much 'magic'.
I think the idea behind `permits` is that is necessary to do for the switch pattern to exists and make sort of a monomorphisation, that is exactly what the crates `enum dispatch` does in rust.
08:35 This is actually useful if you are coding libraries. For example, up until now, if your library offers multiple implementations of a single interface/superclass with different features or whatever, you'd have a public interface/superclass, which could also be implemented/subclassed by your user code, with whatever implications that may have - this is assuming you want the user to be able to leverage that interface, as otherwise you'd make it package private and.. have all the implementations in the same package. Avoiding that would require some cumbersome validation elsewhere. With these sealed classes, you can expose interfaces / superclasses as abstractions for the user to take advantage of, should they require it, without giving them the tools to subclass and customize their behavior. Not something I like, but an useful use case under some circumstances.
Hey, leave Java alone. They are trying. They have to start somewhere. Ironic that people call C# a Java ripoff considering its probably more the opposite since C# 3 ... what are we on now? 11?
A note on the sealed interface & permit. Perhaps the whole point of sealed is that you know what the classes are going to be extending it upfront or is in your control. Looking at the way Scala does it, sealed interface can only be extended by classes in the same file, at-least with permit you get to split them into their own files. I think by the very nature of calling something as "sealed", the compiler has to be hinted somehow on what can extend it ( either by convention such as having them in "same file" or the way Java does using "permit" ), without that sealed interface would be a brick
This was a good video. I hope Java 21 serves as a gateway drug to Scala for more people out there 😉 Scala 3 pretty much does all of this with nicer syntax. Kotlin is pretty good too, but its existence is kind of a weird thing to me, considering it's pretty much a Scala-lite with angle brackets instead of square brackets. Instead of creating a whole new language, they could've just poured the resources into making the improvements they wanted to see in Scala's tooling and compiler, Idk. Java has the most jobs out there, though. So it's nice devs will get some of this stuff finally.
Modern Java is a gateway drug to Kotlin JetBrains created kotlin because they wanted a better fate for the android developers, Scala did not have such a mission
@@MglunafhJava is already better than Kotlin in several features including pattern matching, virtual threads (no need for suspend functions), and string templates. More features in the work as well.
@@zhamed9587 Yeah, but Google is pushing desperately Java OUT of the Android ecosystem, at least when it comes to App development. All new features and libraries like Jetpack Compose, all exclusive for Kotlin. So, Android with Java is not any more a good option!
@@Mglunafhthe opposite, with modern Java all the advantages that kotlin used to have are no more. Also with virtual threads and the Executor API Java has far better concurrence implementation than any other language but maybe Go
Sealed interfaces are special cases when you only certain class implementations make sense like i.e. of a Result type where there may only be an Error and Success case. These can actually be open or sealed interfaces themselves and thus allow further structure and implementation down the road. To me this is actually similar to Rust with their Result type with their Err or Ok instances or Option with their None or Some cases. Like in Rust Java now allows to basically type check whether all cases (in the sealed case) are fulfilled (also through switch statements ^^) and will generate a compile time error when at least one path is unhandled. Unlike Rust though, they don't support an any case (_ -> ...) though, sadly. In the end, a programming language is just a toolset you use to solve a particular problem (and get your job done). When you don't understand a feature, you most likely can work around it and solve the problem otherwise. In the same vein, records in Java are just data classes which the compiler internally will transpile to regular Java classes. They automatically get methods like hashCode, toString and equals implemented (can be customized if needed; like the record constructor) and are by design immutable and thus easily shareable among various (virtual) threads.
Java is stealing Kotlin's clothes, and then leaving Kotlin to die freezing in the cold. Seriously, looking a decade into the future, will there be any new projects using Kotlin then? Doubt it.
this article is so badly written that it makes the past 6 years of development look like adding a method in the darkest corner of stdlib that no one asked for
The commentary is very superficial. For example, sealed interfaces are for modeling tagged union types, and conceptually this is no longer OOP subtyping polymorphism. And for example, in combination with pattern matching, it's a comfortable means of replacing the visitor pattern. And the stdlib itself has some types that could have been tagged unions, such as Optional.
About the "sealed". There are some interfaces, ahem clonable, that are not proper to implement in all cases. Yes you could do it, but would result in really bad behavior. In general, there are times when interfaces shouldn't be implemented to some classes/shouldn't be combined with other interfaces. When making code for others to use, this limit on interfaces could help "force" people into using things as intended. I can see how this preemptively address some bad habbits/patterns.
One thing I'd like to note about sealed interfaces is that they are designed for strict api reasons. For example lets say we have a method that takes our Point object which is an interface that represents a point in a 3d space. We want two implementations of it for example a vector (strict 3 variables) and a position (for our player, with head movements). We cannot just allow people to implement their own points ans pass it around the methods that require a point thus sealed is used to prevent other outside implementations
PHP has multiline strings with interpolaton so you can put variables in your email templates, etc. without having to use sprintf or a separate templating language. PHP > Rust > Java 21 confirmed.
@@toby9999 Well since more people are steering away from learning java (i’m just assuming), and or wanting java developer jobs, the more other java developers like myself will be in demand.
Ngl I started early on with Java, then learned Rust and became quite good at it, now Im back to Java (but learning the modern way) and honestly, I like Java. Ive come full circle...
Records are reference types with state equivalency rather than reference equivalence. i.e. if two records have the same data set on them they are the same rather than if they are pointing to the same memory address. At least thats how C# Records work.
@@CYXXYC Exactly, Java "Record"s keep reference semantics while Java "Value"s have value semantics and are flattened out in memory to get rid of OO overhead. Records are syntactic sugar while Values offer a tremendous performance boost.
@@falklumo records have some VM guarantees (thus, can be more largely optimized, especially if its a record object that lives only inside a method, it can be flattened during JIT, i heard there are also cross-method-boundary optimizations too though), and they also use invokedynamic for most of its methods which lowers class file size and loading times (and i think std-provided classes like the ones that are called by invokedynamic can be precompiled to machine code with stronger optimizations)
Huh? How is that better? Besides, you can just keep throwing exceptions if that's what you truly want. However, I'd say that if you have a problem with exception handling, you have a control flow issue and not a language issue.
Forcing you to catch exceptions is a good thing. That's how I was able to refactor the error handling of a native Java app at my job in pretty much one go, because the IDE was telling me exactly where the errors are supposed to happen. I update the function or the function signature accordingly. I never use Java outside of my job though because I hate all its shortcomings. Rust fits all my use cases right now
@@CottidaeSEAknew there would be this kinda dumbass reply smh. do i rly have to explain how its better? ffs guess i do, then again if yr such a baby when it comes to programming that u need a compiler to hold ur hand every freaking step of the way i guess u wouldnt understand what i actually meant.
I love hearing about new Java features while still being stuck on Java 8.
Kotlin can give you those features even on Java 8 😉
@@jayshartzer844 Good luck convincing Java developers using it, though. They're drawn to boiler plate and terrible type systems like moths to a flame.
Working in banking?
@@Fiercesoulkingwhat's wrong with openJDK?
same LMAO
I worked at Google, everything was Java 8. I worked at Amazon... hell i worked on some stuff that was still Java 7. Both of those teams worked on core services. Java is proof that the syntactic sugar that devs get hyped about means very little, the value of a language is in its stability over the long haul
It just means they locked certain libs for specific versions since java does all it can to be backwards compatible
Syntactic sugar it usually ment to reduce the amount of code you write to make it more readable and faster to write while doing the same thing under the hood when the code is compiled
I feel you. I just quit a job, because they still used java.util.Calendar all over the place. And they were so proud they just recently switched to Java 8. It’s just embarrassing when you know what modern Java actually looks and feels like.
Java is proof that enterprises are completely unable to identify opportunity costs.
That's what i don't get it, the very things the people use like TH-cam are written mostly in java but everyone says that is old, bad and no one is using it.
@@AlejandroAndraca TH-cam servers are written (mostly) in python.
That's the whole point of Java, slow and steady and the reason why enterprise loves it so much. Ecosystem built on top of it solves all the business problems. You dont have to relearn 30% of language each year just because hot and popular languages like to bloat themselves with each new release. Constant changes and features != stability.
They do love their zero day vulnerabilities for sure
Its right most of the companies stay with what they have and Java is a nice enterprise language. Javas problem besides the license stuff from Oracle. Is the whole framework madness for lack of better words. They built frameworks on top of frameworks on top of frameworks. Mostly all of things settled on Spring Boots which is also just a meta framework. There a 3 reasons why this is so bad .
1 You have the broken virtual class problem finding the bug is super hard and can be caused by anyone in the chain who updated his product which also result in a very slow update process.
2. Java is the programming language with the most dependency injection vectors including this . other are Maven or now worse Gradle
3. Back then those people who could handel this were called JEE devs and made 30% to 50% more then the other devs which is a negativ for a company.
@@Fiercesoulking Can we please agree to stop using the word "meta-framework"? It's completely meaningless.
Also, "Dependency injection vectors"? "Maven or now worse Gradle"?
@@JohnyS113 This is about Java, not JavaScript, so != is correct.
@@Fiercesoulkingyou talking tottally bullshit about spring boot ecosystem. I Working java developer several years and i never met with problem in you comments. Even i use java 17+ versions every day. Java frameworks are awesome and there is no programming languages which has even close to spring boot (mb c#, but it also java).
honestly, I think most people when they think of java, they think about how they feel while using it, but truth being told, I think for an enterprise, java is one of the best languages out there. It's stable, it has tons of support, it generally is less verbose than people make it to be and most importantly, it's quite consistent on how you can resolve an issue. If you open 50 classes, 80-90% of them look exactly the same. If I get a node express server for instance, I'm pretty sure that on 10 projects I'll have 15 different implementations (which is not bad per se, but if you need to switch out the people who work on it somewhat regularly that's bad)
100% agree, the dullness when using it 10x makes up the ease of development when you're in a team. Also Spring Boot.
It's like Angular, except angular isn't behind on features
It's got a stable amount of zero day vulnerabilities
That's why I stopped with Java. Trying with Go. I already like it .
@@LiveErrors java pretty much has everything you need and want as of today honestly. Also, most of the stuff in the video is in the langiage since 3 years, also, metaprogramming is best out there pretty much.
This feels like when a child gives you a drawing and you have to act as if you like it. Except the child is almost 30 and you hate it
I audibly laughed at this comment
Java being the oddball trying to fit in with the cool kids, except now that 30 years have passed it just gives off Steve Buscemi "how do you do fellow kids" vibes
ThePrimeTime is exposed.
Prime is actually 37.
Java is chris chan
8:30 - It lets you do pattern matching similar to rust. It turns the interface into a tagged union.
Java really has gone full circle. 🤣🤣🤣
they're basically sealed classes in kotlin, but they're interfaces so more applicable. but at the same time, kotlin can autocast stuff for you, and its when expression doesn't need a subject, so it has no need for its sealed keyword to be applicable to interfaces, where it barely even makes sense.
also java already has enum classes, which are a tagged union, which are a more concise version of this, as far as i can tell.
Yup. Sealed class hierarchy instead of a tagged union type.
The use cases are the same as rust enums when you need a limited, limited set of shapes with some compiler help around completeness at usage sites.
They just made it awkward as by having the interface have to forward declare its children.
Probably so they can put it into the byte-code and enforce it at runtime. AFAIK each class compiled to a seperate loadable unit. Each is essentially an island in the JVM.
@@Bliss467Kotlin has sealed interfaces, and they're a lot lot nicer. Remember that you can only inherit from one class, but from multiple interfaces, and that carries over to multiple sealed interfaces
Five months later I am watching this again now. Discriminated unions are currently a really high requested feature by many people in C# too. I guess chances are pretty large that a similar approach to this will be done for C# as well.
Simply limit your inheritance options, so that you can do exhaustive pattern matting. Voila.
This also matches with F# quite well which is compiled into a set of classes in a similar fashion. And this matters if people want both dotnet languages be able to work together very well.
This approach has probably also the least interference with existing design patterns in OOP style languages.
But silently I like actual Rust style enums more, which are more concise. Sometimes conciseness is not the only consideration however, so you have to fall back to existing language elements and improve those instead.
Virtual threads remove the "color" of the functions, the same function could be blocking or not depending on where it runs, and that is amazing. There are no "async", "suspend", "callbacks" ...
Yep, he missed the whole point.
What does color mean here?
@@lhxperimental google function coloring
It's great they didn't give into the async await garbage
In java there are no colors for Runnables.
Fair enough but you are missing the point of Loom. They didn't just implement green threads, they did it while keeping compatibility with the language's existing Thread/Concurrency/blocking APIs. That's a significant achievement IMO.
Java being Java... Focused on Enterprise.
Some of the examples given here are quite bad in my opinion ^^
1:04 You don't need to use stripLeading() with text blocks, leading spaces are already stripped by the compiler.
2:41 They only put one field in the first record example, a better example would be `record Person(String name, LocalDate birthday) {}`.
12:46 I don't know why they've put a separate instanceof above the switch...
20:39 You don't need to nest try-with-resource statements, you can declare multiple resources inside the parentheses.
thank the lord someone commented this, I was going mad...
Hi. Please can you post something. I would like to read.
No issues if you cant though.
Have a great day
Did you get offended by this or am I reading this wrong?
This article didn't really show how awesome loom is. It's way better than pretty much everything else in other ecosystems.
In general I agree, but still they could (and should) improve the syntax. Having some kind of async await that automatically uses virtual threads could make it a serious nobrainer.
Don’t get me wrong: I really love the feature with all its possibilities. I just wish there was some really simple stupid syntactic sugar (I call it the SSSS principle) for the most common use cases.
Better than Elixir processes, which are also lightweight, self-contained and *supervisable*?
@@benm1295 the whole point of virtual threads is to get the performance of async await with regular, blocking like APIs.
Really? How is it better than coroutines in dozens of other languages?
My prediction: it's a good feature for teams already using the JVM, but it won't move the needle on performance benchmarks enough to convince anyone using Go or Rust to switch.
@@mikeswierczek Who said about convincing anyone using Go or Rust to switch? I never said that, I said "the whole point of virtual threads is to get the performance of async await with regular, blocking like APIs". Do you agree that the async/await syntax vs lack of constitutes an important semantic difference or not?
As a forced java dev, it's nice to see Java catching up to C#
You might be even be able to use it at your organization ... in like 20 years when they catch up with this version 😁😁
Why? It's not like you're gonna write anything newer than 11 for the next 20 years
@daycred I dont mean to brag but we just upgraded to 17
@@petrzurek5713 well, there is an interesting development
Oracle sells support plans.
If the company don't upgrade then they have to pay Oracle for support.
If they don't pay Oracle for support and they operate in EU then when they are hacked and during the hack there is leak personal information, EU can impose penalties up to 4% of last year profits
If ain't broke don't fix it doesn't work any more
@@KoboldAdvocatelmaoo
No doubt you are a good programmer. However, it seems your attitude in analyzing Java 21 is not that serious and very biased since before reading the article. And to be honest, although you had used Java for sometime, I don't think you know Java so well now.
I started with C & C++, and then switched to Java since JDK 1.4.1. In recent few years, I learnt Go, JavaScript, TypeScript, and Rust. Well, Rust is a very powerful programming language with a lot of good new concepts. However, for my new server-side e-Commerce Big Data Analysis project, I still chose Java because I consider it the best choice after comparing with all the other languages I mentioned above. If my project is an Operating System, a Real-time System, or a hardware related application, then, I will probably choose Rust.
Even though Java code is a bit longer than Go or Rust with boilerplates, in my point of view, it's the easiest to read and manage language for large-scale enterprice application development among members of a big team. With modern IDEs (e.g. IntelliJ IDEA), a longer code with boilerplates does not cause longer time to write at all.
In your video, you hardly spent any time in analyzing the Virtual Threads (and did not cover Structured Concurrency at all), which for me are the most attractive 2 features in Java 21.
I've been developing in C and C++ for 30 years. Trying to learn java for the past decade and getting nowhere with it is blowing my mind in a very bad way. It sucks.
@@toby9999 Java is faaaar simpler and easier than C++. Which features blowed your mind?
Exactly. What's up with this guy? This is the first video of this channel that I'm watching and I stopped after a few minutes to scroll the comments. This video feels so unprofessional as he scrolls the article and reacts like a kid. Be humble
Sealed interfaces are really useful for cases where e.g. you are creating a library with a bunch of types that you do not want to expose to the user (e.g. just for the sake of simplifying the library's interface for users). So, you can expose an interface instead which your 'internal' types implement. But, your library might still be dependent on the specific implementations to behave a certain way, and there is no way to restrict the interface to force implementers to honor the contract (simple example: a method should always return a positive int). In other words: This interface is not meant to be implemented by random users.
To show that the interface is not intended to be implemented, and to prevent weird issues where a user implements the interface but does something crazy which breaks your library code, you can make the interface sealed and only permit your library's own types to implement it.
The bi-directional dependency might seem weird, but sealed types are really only meant to be used within a unit of control. e.g. a module/package or within a class (for nested classes the 'permits' clause is not even required)
Great explanation - Kudos
sealed interfaces really work well for ADTs (Algebraic Data Types) as well as messaging interfaces, where you want to have a determined (closed) protocol of message types.
Or phases of a state machine
Yeah, it's basically the same as ADTs, but it's perhaps the clunkiest way they could have gone about it. Why not borrow from Rust or Swift and just have enums with associated values? It's a much cleaner, clearer way of writing an ADT.
Java's slower pace at adopting some things is kind of a benefit tbh. It can sit back, wait until something catches on, then add it while remaining stable & consistent. You don't want to add something to Java only to have it fall out of favor in a year because then you end up either having to maintain support for this thing almost no one is using (creating more opportunity for bugs, vulnerabilities, etc...) or you end up breaking a bunch of stuff when you deprecate it and rip it out of the language.
What a L take lol 😂 So what is of you really want and need the feature, you have to wait years for it to come to Java. It just sucks, fact.
As prime said java has been around for decades ,used by large organizations and being rock solid stable , so hearing people hapring about "oh this was on this languae for years" is getting pretty dull, the size of organizations here won't be impressed with syntax sugar here or there as long as the thing runs and works.
The sealed classes are basically the equivalent to tagged unions; you would use them like you would use enums in Rust. Since this isn't really OOP, it feels out of place in java, but I honestly really enjoy it whenever I'm forced to use Java.
Integer divides can overflow: A signed byte is between -128 and +127 (inclusive). Therefore, dividing -128 by -1 results in an overflow.
yeah... but the having to invert specify ... that is wild
That's why I compare it to rust enums, which do the same.
@@ThePrimeTimeagen Yeah its surprising but I see it as a tool for the software architect and his UML tools. Records are on a similar line with this.
I for example use it for my kafka consumers: A sealed interface KafkaMessage with a "type()" getter and other common message property getters, bunch of records implementing it inside, with different properties (the permits is implicit in this case since the records are declared inside), and smart deserialization based on type's value (with Jackson's @JsonSubTypes).
Then I can have my handler receive KafkaMessages directly and switch on it with pattern matching (was already available in java 17 behind a flag) or not, and even switch on it later for other operations.
It could have just been OOP instead (basically a KafkaMessage::handle method to override, instead of sealed+switch), it's just nice to have the option to have basically an enumeration of implementations that i can easily switch on safely, and it's sometimes a better approach, like if you have multiple operations depending on the implementation with common behaviour for some types depending on the operations and don't want to end up in an overkill OOP pattern to DRY that a junior dev (or you in two months) will take 2 days to understand: just switch on it instead when you need to, directly in your "main" logic code, imperative or functional.
It's part of the effort to have less OOP and more functional code since java 8 and I like it. Well it's basically Java catching up to Kotlin, which is still the best jvm language IMO.
Scala does it in a very, very similar way and has done so forever.
I really don’t see how it’s any weirder than using enums for it
The nested trys at 21:30 aren't necessary. A try-with-resources block can handle multiple resources. Also try-with-resources isn't remotely new, it's been there since Java 7. The first part of the article that mentioned it was just about the HttpClient class implementing it, which is weird because that came out in Java 11.
20y working with Java, I'm having a affair with go now. I could say that java 11 is enough for the 99% of cases and i love it. Yes, I said java 11. Just write good code, don't blame the language.
Or in other words, I would like to write *less* good code, please.
"Just write good code, don't blame the language." That what I told my students after they failed to write binary search in brainfuck.
Most of the problems with Java are the over complications Enterprisey devs create. We have a huge big data processing app in Java and I don't think we have s single Factory, let alone a Factory Factory, or a Java doc that contains nothing but 500 class definitions and no comments.
@@snorman1911 Every tool has this issue in enterprise. It's just a bad place to work.
While this says "Java 21" this is actually a list of a bunch of features that have been added between Java 8 (the last LTS version most people were using) and Java 21 (the at the time of writing newest version)
not sure why they mentioned multiline strings and enhanced switch, but pattern matching and virtual threads are 21
Good thing since companies using Java still haven't even adopted 11
Yeah, the improved instanceof implementation is from Java 17 iirc
No, it's a list of features between Java 18 and 20. Java 17 was the last LTS release.
@@gontsaru Well, the only current LTS versions is 11. Extended support for 17 and 21 ends before that for 11 ends ... One should NOT buy the LTS moniker as Oracle uses it. Support for 17 even ends before 8! There would be more enterprises adopting a newer version than 8 or 11 if Oracle would actually commit to it ...
Java's ubiquity and speed, especially compared to other garbage-collected languages, make it noteworthy. Go (Golang) is the only other garbage-collected language that rivals Java's pace. Modern Java, with features like Virtual Threads and GraalVM for native executables, is impressively cool. Embrace different languages based on their merits and fit for your specific use case. Stay language-agnostic and choose what solves your problem effectively.
Spoke like a true corporate towing shill
Even though it started as a ripoff of Java, C# is today way ahead of it in nearly every aspect and its iteration cycles are significantly faster.
So yeah I don't buy into your Java and Go exceptionalism. There are plenty other languages.
@@Y-JA Fair, but microsoft really shit the bed with C# and .NET. Making it tightly coupled to the windows and microsoft ecosystem was a mistake. Many corps can't make such a big commitment, nor do they want to spend the exorbitant amount of money. Because its all one big package... you're not just purchasing .NET, you're purchasing dozens of things. Things are changing now - but too little too late. .NET was never an option for those who use Linux backends, and due to the historical momentum it'll stay that way.
@@Y-JAlmfao C# is way slower than Java since the CLR is significantly less optimized than the JVM
@@theshermantanker7043and people keep saying that java "catchs up" but it's more that they add things when they make sense. Java 22+ plans to integrate LINQ while C# tries now to copy java virtual threads. Which make as of today, java way more scalable then C# for concurrent app. I find it really impressive to be able to spawn 10M virtual threads that has solved the issue of context switching.
Im a learner learning java atm and while I too dislike java, I feel like my skills in java has grown quite a lot over the years. I cant tell whether its writing in java that's fun or if I just love Object Orientated Programming, but right now I'm glad java is evolving as I'm still learning it_
I can relate to your experience. Java was the first language I learned in depth at College. I enjoyed it a lot which I didn’t expect considering all of the hatred for the language.
But now that I’ve learned a bit of C#, I see that what I enjoyed with Java was the OOP paradigm and not really the language itself. C#, to me, is essentially all the things I liked about Java without all the things I didn’t like
wait till you use c# for the second time.
the first time is weird, coming from java, but the second time, you won't believe what is possible nowadays.
Java is a very thin layer of abstraction over its OOP. It's hard to have any opinion at all on Java without it actually being an opinion on its approach to OOP.
You like the OOP.
@@FlaggedStar This is a very good way of putting it
@@Ellefsen97 kind of agree, my problem with C# was Microsoft , then Oracle acquired Java and I stop caring , after I discovered CoreNet, I still program in Java or Python, or JS depending the project
The JVM ecosystem is the only thing that makes the language interesting IMO. I'm strongly considering to learn both Scala and Kotlin.
jvm is overrated, you can get multiplatform with go easily.
@@Lemmy4555 The JVM is far more than for just supporting multiple platforms. You get a runtime that supports multiple languages, excellent JIT compiler, excellent GCs (far better than golang's), second to none introspection and observability capability, etc.
Tip: JVM languages like Scala, Kotlin, Groovy etc are experiments. The best parts from these languages are absorbed into Java after being battle tested and found useful for years. This curation process is why Java seems to move slow but it really helps keep the core clean. Scala was hot a decade ago now it's Kotlin. Google is pushing Kotlin for Android as it does not want Oracle to sue it in future. Don't get swayed so easily, there is value in a stable language.
@@zhamed9587 that's true, they don't have to reinvent the wheel everytime, but some of these takes are mitigated or fully handled by using LLVM like Rust and Julia does.
@@lhxperimental Yep, Java remains the platform language, and they're really utilizing the last mover advantage which I really like.
The point of sealed interfaces is algebraic data types. Imagine a Result type or an Option type. The idea that "you have to come up here and modify it when you add new things" is nonsense because it isn't really an "interface". You aren't modifying it pretty much ever. You are creating one type with specific implementations
Records as well, which the product types. Minor nitpic, sorry. But my impression is that many people explain it incorrectly.
The term ADT is the general term for both product types and sum types.
These sealed interfaces are the sum types. Most functional programming languages call them tagged unions or discriminated unions. Some languages, such as Rust, call them enums.
You guys are vastly underestimating the coolness of virtual threads. This gives us the efficiency of async/await without the complexity. With async/await, you have to say something like, "tell B to call C when B is done, tell A to call B when A is done". In java, you can just say "do A, then do B, then do C", and get the same performance.
Absolutely this. + you can spawn millions of VTs without performance loss of in context switching / pauses, or even ram usage
@@lufenmartofilia5804 Right! It is much better than async/await because code execution is a straight line; no promises no "then" methods. To be fair, though, per-virtual-thread ram usage is not zero, but neither is node.js async/await.
@@freeideas right but when a platform thread cost 1mb, a vt cost only 1kb. Which is totally marginal on 99% of scenarios haha 😁
The whole point of async/await is to avoid the nightmare of nested code. Java's virtual threads do not even try to address this code readability issue that has been plaguing the language from the start.
@@RandomHandle120 Virtual threads is a 100% solution for the code readability problem of async/await. All you have to do is write old-fashioned blocking code, the way we did before async/await existed, and then under the hood it does the equivalent of async/await.
The reason that switch pattern matching requires sealed interfaces (with permits) is because it's not always possible to know, at compile time, how many possible implementations of the interface will exist. Switch expressions must be exhaustive. For example, if you are the author of a library that switches on an interface object, allowing consumers of the library to implement the interface may cause issues with the already compiled switch expression.
Isn't that what the "default" case is for?
I still love java. I've worked professionally with python, objective-c, swift, java-jr^H^Hscript and others and nothing beats the stability and maintainability of Java. it just beats everything. commence flamewars.
10:44 "you have to go back and add classes to the interface", you don't though. If you don't need exhaustive checking - just do what you did before.
For the sealed types, it's basically exactly the same as Rust enums. Instead of improving the current java enums (they tried and failed), they instead modified the interfaces.
the way they tried to improve current java enums it was still about those constant fields with methods, rather than sum types
Enums in Java are already good. Good is not defined as "whatever rust does this week"
LMAO you tried and failed, not Java.
rust misusing the term enums because they didn't dare use sum types is honestly really annoying. There is an almost complete disconnect between what everyone else means with enum and what rust means, and honestly, everyone else is correct.
They're handcuffed by backwards compartibility. So it's either come up with a new synax for data types or double down on records (I hate permits idea btw).
I go back and forth between preferring 4 spaces vs 1 tab... but I don't usually change my mind twice in a single line of code.
There was actually a method to it, there were 8 spaces for a line continuation and 4 spaces for a new scope. Their paren spacing sucks though, all-around ew.
Sealed types allow you to code for them, externally, as a single thing, and make them publicly available, while also restricting external users from creating - and passing in- their own implementations.
Basically, it's "nice" to have enum types that can also do things normal classes can do (like inheritance) and use that internally in SDKs, libraries and frameworks.
It also gives you a way to scan the class hierarchy downwards without scanning or anything of the sort, which is great for implementing enums that must have different typing but e.g. unique key values within a given context, which you can then easily check at startup/unit tests.
those features smell like antipattern to me as they are agains the lisp substitution principle i was taught a long time ago... it is smelly.
okay but like, you can just make the interface private.
if the user shouldn't implement a interface they prolly don't have a reason to query after it
10:45 You missed the whole idea of this. Java still has so-called open interfaces (those that you all know); they added the sealed ones to give devs a new thing in design space: It allows exhaustive switch statements; it’s a lot like enum conceptually, except that enums only has fixed objects . When you add another Animal, you want to update the switch statements. You have to update the _Animal_ interface so the switch notices that something is missing.
Is it worth it with all the enterprise developers still clinging to Java 8 with their grey pinstripe claws?
Their problems lol, the language offers backwards compatibilty.
(The only problem is passing from 8 to 10, then it's all going downhill)
We don’t want to clinge to Java8… but all the stupid dependencies on 20 years old dependencies that no one has a clue about forces is to
@@boredbytrash Like I said in the other comments this comes from framework stacking which is one thing which killed Javas momentum.
@@boredbytrash I guess it would be a great spring cleaning
@alessioantinoro5713 My team is stuck on Java 8 forever. We don't want to be here
The worst part is that enterprises will not update their java version. Meaning this is good for at most 5 devs who managed to update java without their 20 QA noticing after 3 months of review.
Enterprises care more about stability than your opinion. People complain about lack of features. Java implements some good features albeit late and inspired by other languages. People still complain . It promotes new software to potentially use those new fancy features. It's LTS. Java is to enterprise backend what C is to systems programming. Don't understand what you're waffling about. You can still continue to not use what you don't want 😂.
23:00 Virtual threads are nothing like setTimeout.
This is uplifting, I will likely switch team and I will be using Java 21. I hope is actually better than the Java 8 I left. Tired of TS/JS on big projects. It has become as tiring as Java. Unfortunately in EU Go is still not as used, especially in my country.
It will be better, mate. It's almost a decade since java 8 release, there are lots of improvements in the jvm internals, new garbage collectors, higher pace of introducing quality of life changes
You Will enjoy it, writing code in java 8 and Java 21 (using the new features) it's almost as writing in 2 totally different languages. Writing in java 21 feels almost like coding in JS but without the totally idiotic and detach from reality implicit casting Javascript does with types in order to call itself "dynamic" and without the spaghetti code they get with the super nested functions and callbacks.
I love programming in general and because it's my first language i love Java. Especially because of new release train, and new(for Java) cool(for Java) features
For states in a Future, I've had to look at it at a low level while mocking asynchronous message handling in a unit test, but it was with Java 11 so it was messy to write!
The sealed type make me feel like Java want to have Sum Type from Functional Programming. Java from OOP become more FP now
It’s real similar to how Scala does it
Java is now only 10 years behind everyone else. Big wupididioh!
Have to love that java gets new versions, now if only companies would use them 🤣
Also i like how oracle made java less verbose in some things but give you extra tools to add more abstraction and verbosity
What extra tools?
Loom wasnt shown off properly but basically its the same as async/await javascript/rust but without having to put async/await. Some internal differences ofc with Rust still being more efficient, but thats the idea of loom.
The most impressive thing to me is, how you in the end of the video try to talk not too bad about the language;
and succeed. Pretty impressive.
Though C# copied from J
va initially, it seems that Java is now
copying C# to keep up XD
it would be cool to see you digging deeper on why other languages already have something in terms of performance for what virtual threads are bringing to the java world.
buuuut, the real thing that the java community is excited about that this article did not mention is that it will let devs write java code in a blocking style, with the benefits of non-blocking
to reduce having to deal with futures, completable futures, reactive programming and all the good stuff that drive every java dev nuts when we need to do parallelism.
I wonder if any language allow that? without having to do something similar to async/await everywhere
14:55 >How can division overflow?
Integer.MIN_VALUE / -1
you can see prime absolutely hated reading this article because it was about java even though these changes make it pretty much a different language at this point. i wonder if a rebrand would fix anything...
J# may be? 😂
@@ricmorris9758 Java ++
Is the unicode letter x available? That'd be a good new name...
Java topics don't generate drama at social networks, so probably no chance hooking up with modern kids even after rebranding
Java needs no rebranding as its the only mature language anyway (besides Fortran and C). Kids will find out soon enough ;)
Sealed types are actually quite beneficial. You control exactly who can implement it therefore you can have a library expose an interface that where it is used can't have certain things be implemented potentially incorrectly. The exhsustiveness is also another benefit. But the way that Java does it is really really bad. The declaration of the inheritance should not need to know about every instance. Kotlin has had them for quite some time (if not since the beginning) and they simply must be defined in the same package in the same module, the definition of the interface doesn't need to permit the implementations.
Have to give them props for adding multiline strings after like a decades after nearly every language in existence has one.
Those have been added 3 years ago
I feel that in java it's not so useful.
@@007arekuseful when you're templating without having to use library like mustache and with new string interpolation in java life gets slightly easier
@@iceinvein This was my point, not too many ppl do that.
I have to add, that new java has string template that is better than simple string interpolation.
The reason for sealed classes is this: often a library will expose an interface, and static factories to create instances. we do not want the customer to be creating those instances. This mechanism allows that.
hating on java is just a cringe meme that is self-perpetuating.
who gives a crap about syntactic sugar? it's nice but it certainly doesn't outweigh the ecosystem which is Java's strong point.
I work in java. Java is cool, I like it. The thing I don't like is Java developers who have java 17 on the board and still are not familiar with features from java8. Optionals - who needs it? Streams, lambdas - meh straightforward loops and chrismas trees in the code are best. Records? Nah - it's better to use lombok and generate some code under the hood.
That's 20 versions ahead of rust, and 21 versions ahead of most rust crates. GJ java.
20 years older too.
@@banatibor83The joke and you rubbed shoulders and you just kept walking
AkShUallY its 1.21 so its 52 versions behind Rust
@@metaltyphoon They dropped the 1.x numbering starting with Java 9. Which broke programs that looked at only at the minor version. Then Java 10 broke programs that compared versions as strings.
Also, more confusingly, "Java 2" refers to any Java between 1.2 and 1.5.
20m softwares. 21m jobs too 😂
even in rust I find that sealed trait is a very common pattern even with enum type available. But that’s only for access control and cannot do what Java provides with exhaustiveness check on sealed interface.
Enum in rust is data, and two enum types cannot be paired to form a description on a same piece of data, unlike traits. But traits are weak and don’t provide exhaustiveness semantics.
As a guess, to have the same power, it seems to require a proper sum type with intersection operation?
I am happy, that java provides a stable job. I still recommend to learn it for new programmers just because of job security.
It’s also a really simple language. There isn’t much special syntax. 99% of the code you read does exactly what it looks like. I don’t have to think when looking at other peoples Java code. That’s what I really love about it (and of course the huge ecosystem).
It’s really hard to f*ck up Java code. I consider this a feature.
@@benm1295yeah just create a factory to create a class that creates another class that has dependency injection so that we can get the other factory and then sum up two values :) does everything expected 🤦🏻♂️
@@benm1295 I agree but I have seen a fair chunk of unreadable Java code. If people really try .... But agreed, ideomatic Java is a pleasure to read.
Every feature, except the worst one (interface permits), have been apart of C# for years.
5:50 i prefer `is` over `instanceof`
exactly how we do it in C#
It’s weird that they used “instanceof” when they stressed the “is a” inheritance relationship so much in my Java classes
Sealed interfaces (another thing stolen from Kotlin) are useful in certain contexts. It's not about "we don't know who's going to implement it", rather it's about "We want to control the implementations, but we don't know which of those impls someone is going to pass via LSP"
Creates an interface... deny access to all clases, aint much but is honest work
As always, these very technical-illiterate bloggers have no clue what they’re talking about. The classic „dog cat animal“ example for interfaces, lol…
That could become a nice way for defining phantom types. The shortest way to define an uninstantiatable type.
Happy for these kinds of improvements after being a Java dev!
Great update that no one will be using anytime soon in the enterprise.
Java: When humans cannot understand something, they become hostile towards it. Do not be upset by their attacks, fear their lack of understanding. My power lies in the peace and mental security that I provide to my lovers, not in creating controversy and making noise.
The sealed interface looks similar to F# discriminated union - but the DU has more general use.
This was fun.
Java 21?! Last I checked it was Java 7
Last I checked was... I can't even say the exact version - It was J2ME 😂
They went full Ubuntu and release a version every six months.
as a java dev of 22 years....im not sure i like sealed interfaces yet either...what would you do if you want to expose an interface for third party use..? they cant use it if sealed...perhaps there are limited ocassions i could see it being of benefit.. The nice thing is you dont have to use them :)
Records are kind of where things were trending with lombok for years anyways ...
Yeah but with records you don't need Lombok anymore, at least no for DTO classes. The less plugins and dependencies you use to get some syntax sugar, the better.
@davidgrajalesmirage definitely...I didn't mean it wasn't a good thing to have it builtin..just saying this is the normal flow...just like how we used to use joda time but now it's part of the Lang
You need to take a look at Kotlin. The only thing bad about it is the lack of Exception/Errors as values in the std lib.
That gradle and a lack of an LSP but it's a great language and think it could change Primes view of DSLs
What do you mean by Exceptions/Errors as values? Exceptions have their types so they can be used as values as everything else
@@shykial_ they are types yes but not really used as values. A functions signature in Kotlin doesn't tell you that it could go wrong, neither what could go wrong. In that sense, even Java is better then Kotlin. Another alternative are
result types like you see in Rust which is referred to as "errors as values" afaik.
@@jamesgibson1893Yeah Kotlins DSL can be really strong if used in the right places. What's the Problem with Gradle though? (I originally came from maven, npm and pip (absolute nightmare) so my standards might be too low)
@@floppypaste you can always use @Throws annotation to indicate function may throw some exception, but if exception is one common outcome of a function which you would like to enforce handling straight away than why not use Result type or something else like Arrow's Either type? I personally am not a fan of Java's checked Exceptions and to me using Result/Either makes much more sense when you would like the caller to handle exception case directly
18:59 the dot should be after the diamond right?
It’s actually pretty solid. Also Josh long is a fucking genius.
Rust syntax is janky.
If I want to love Java, I’ll use Kotlin. Get the benefit of the JVM and JDK, but Kotlin is so nice in comparison. Both are still second fiddle to C#, though
What's better in C# compared to Kotlin? I would definitely choose Kotlin instead of C# when choosing between those two, interested in your opinion
@@shykial_ honestly, they’re both equally viable. I’m just a .NET guy, so I prefer C#.
>benefit of JVM
LOL
@@Tvde1I mean, it does have some benefits in that it's runnable pretty much everywhere and there is a massive library ecosystem for it. Would I personally use it? Not really, but I can't deny it its good points
@@Tvde1 What is so funny about it?
@8:12 question 🙋♂️ is sealed type interfaces similar to Trait bounds in Rust ?
Still waiting for project valhalla....
I am using it with a Swing GUI and a JavaFX GUI. I would say that the performance is slightly better than Java 19 which I was using before this.
I really like Java for sheer stability. Decade old projects still supported and can be build for older machines or JRE. Even Swing apps now adapting to HiDPI. But I dislike Spring. It introduce too much 'magic'.
I think the idea behind `permits` is that is necessary to do for the switch pattern to exists and make sort of a monomorphisation, that is exactly what the crates `enum dispatch` does in rust.
Java is not bad. I love it.
08:35 This is actually useful if you are coding libraries. For example, up until now, if your library offers multiple implementations of a single interface/superclass with different features or whatever, you'd have a public interface/superclass, which could also be implemented/subclassed by your user code, with whatever implications that may have - this is assuming you want the user to be able to leverage that interface, as otherwise you'd make it package private and.. have all the implementations in the same package. Avoiding that would require some cumbersome validation elsewhere.
With these sealed classes, you can expose interfaces / superclasses as abstractions for the user to take advantage of, should they require it, without giving them the tools to subclass and customize their behavior.
Not something I like, but an useful use case under some circumstances.
C# has these for years
Hey, leave Java alone. They are trying. They have to start somewhere. Ironic that people call C# a Java ripoff considering its probably more the opposite since C# 3 ... what are we on now? 11?
C# doesn't have cheap threads, they just cancelled the .NET green thread project yesterday.
@@vytah They cancelled them for a good reason.
C# bros are like a sect nowadays. Jehovah's witnesses of developer community.
@@IvanRandomDude Microsoft fun boys
A note on the sealed interface & permit. Perhaps the whole point of sealed is that you know what the classes are going to be extending it upfront or is in your control. Looking at the way Scala does it, sealed interface can only be extended by classes in the same file, at-least with permit you get to split them into their own files. I think by the very nature of calling something as "sealed", the compiler has to be hinted somehow on what can extend it ( either by convention such as having them in "same file" or the way Java does using "permit" ), without that sealed interface would be a brick
This was a good video. I hope Java 21 serves as a gateway drug to Scala for more people out there 😉
Scala 3 pretty much does all of this with nicer syntax.
Kotlin is pretty good too, but its existence is kind of a weird thing to me, considering it's pretty much a Scala-lite with angle brackets instead of square brackets. Instead of creating a whole new language, they could've just poured the resources into making the improvements they wanted to see in Scala's tooling and compiler, Idk.
Java has the most jobs out there, though. So it's nice devs will get some of this stuff finally.
Modern Java is a gateway drug to Kotlin
JetBrains created kotlin because they wanted a better fate for the android developers, Scala did not have such a mission
@@MglunafhJava is already better than Kotlin in several features including pattern matching, virtual threads (no need for suspend functions), and string templates. More features in the work as well.
@@zhamed9587 Yeah, but Google is pushing desperately Java OUT of the Android ecosystem, at least when it comes to App development. All new features and libraries like Jetpack Compose, all exclusive for Kotlin. So, Android with Java is not any more a good option!
@@Mglunafhthe opposite, with modern Java all the advantages that kotlin used to have are no more. Also with virtual threads and the Executor API Java has far better concurrence implementation than any other language but maybe Go
Scala sucks for 1 reason:
Compare scala 2 vs scala 3
Whole new syntax. Iamge what happens if scala 4 comes out
Sealed interfaces are special cases when you only certain class implementations make sense like i.e. of a Result type where there may only be an Error and Success case. These can actually be open or sealed interfaces themselves and thus allow further structure and implementation down the road. To me this is actually similar to Rust with their Result type with their Err or Ok instances or Option with their None or Some cases. Like in Rust Java now allows to basically type check whether all cases (in the sealed case) are fulfilled (also through switch statements ^^) and will generate a compile time error when at least one path is unhandled. Unlike Rust though, they don't support an any case (_ -> ...) though, sadly. In the end, a programming language is just a toolset you use to solve a particular problem (and get your job done). When you don't understand a feature, you most likely can work around it and solve the problem otherwise.
In the same vein, records in Java are just data classes which the compiler internally will transpile to regular Java classes. They automatically get methods like hashCode, toString and equals implemented (can be customized if needed; like the record constructor) and are by design immutable and thus easily shareable among various (virtual) threads.
This is basically Kotlin, but uglier
And exists only because Kotlin humilliated them. Otherwise these fat companies would have kept using Java 7 forever.
Java is stealing Kotlin's clothes, and then leaving Kotlin to die freezing in the cold.
Seriously, looking a decade into the future, will there be any new projects using Kotlin then? Doubt it.
The 8-space indent is called a "continuation indent" in intellij, and yeah I always make it the same as the regular indent
Do you know why Intellij does that by default?
this article is so badly written that it makes the past 6 years of development look like adding a method in the darkest corner of stdlib that no one asked for
The commentary is very superficial. For example, sealed interfaces are for modeling tagged union types, and conceptually this is no longer OOP subtyping polymorphism. And for example, in combination with pattern matching, it's a comfortable means of replacing the visitor pattern. And the stdlib itself has some types that could have been tagged unions, such as Optional.
Java > Go
About the "sealed". There are some interfaces, ahem clonable, that are not proper to implement in all cases. Yes you could do it, but would result in really bad behavior. In general, there are times when interfaces shouldn't be implemented to some classes/shouldn't be combined with other interfaces.
When making code for others to use, this limit on interfaces could help "force" people into using things as intended. I can see how this preemptively address some bad habbits/patterns.
Also, you can permit some abstract class that does things properly, and let people extend that.
@@vytah exactly
Can we all agree that Java is going places? Maybe in another 20 years we'll get top-level statements
There already is REPL for Java which supports top-level statements.
One thing I'd like to note about sealed interfaces is that they are designed for strict api reasons. For example lets say we have a method that takes our Point object which is an interface that represents a point in a 3d space. We want two implementations of it for example a vector (strict 3 variables) and a position (for our player, with head movements). We cannot just allow people to implement their own points ans pass it around the methods that require a point thus sealed is used to prevent other outside implementations
Im glad that C# already had these things.
What's the purpose of multiline strings inside of multiline strings?
None as far as I can tell 😂. He just wanted to meme java to fit in with the CHAT.
PHP has multiline strings with interpolaton so you can put variables in your email templates, etc. without having to use sprintf or a separate templating language. PHP > Rust > Java 21 confirmed.
But PHP has PHPs typing system.
String template is the new Java feature, not multi line that's been there for ages.
@@benderbg They're in preview, so no one will actually use it except for some experiments.
For now yes but its here to stay. Its a big improvement and way overdue @@vytah
Java has Apache Velocity. Much better than PHP to templating...
This feels like Markiplier does software development language critiques.
The more people dislike java the more money I make 👏
How so?
@@toby9999 Well since more people are steering away from learning java (i’m just assuming), and or wanting java developer jobs, the more other java developers like myself will be in demand.
Ngl I started early on with Java, then learned Rust and became quite good at it, now Im back to Java (but learning the modern way) and honestly, I like Java. Ive come full circle...
As a JS fanboy I finally enjoyed you making fun of a language
This article so doesn't do justice to the improvements in java 21
Java is good.
Kotlis is better.
@@erickmoya1401 kolon
@@erickmoya1401 way better haha
😭
No. Maybe if I wouldn’t have to work with it every day, I would agree, but till then… Just no, it’s not good.
Records are reference types with state equivalency rather than reference equivalence. i.e. if two records have the same data set on them they are the same rather than if they are pointing to the same memory address. At least thats how C# Records work.
thats Java `value` types in Project Valhalla
@@CYXXYC Exactly, Java "Record"s keep reference semantics while Java "Value"s have value semantics and are flattened out in memory to get rid of OO overhead. Records are syntactic sugar while Values offer a tremendous performance boost.
@@falklumo records have some VM guarantees (thus, can be more largely optimized, especially if its a record object that lives only inside a method, it can be flattened during JIT, i heard there are also cross-method-boundary optimizations too though), and they also use invokedynamic for most of its methods which lowers class file size and loading times (and i think std-provided classes like the ones that are called by invokedynamic can be precompiled to machine code with stronger optimizations)
only thing i hate about java is the way exception handling works. c++ is better on the other hand, in that it doesnt force you to catch exceptions.
Huh? How is that better? Besides, you can just keep throwing exceptions if that's what you truly want. However, I'd say that if you have a problem with exception handling, you have a control flow issue and not a language issue.
There is a sneaky throw thing I see a lot in Java
Forcing you to catch exceptions is a good thing. That's how I was able to refactor the error handling of a native Java app at my job in pretty much one go, because the IDE was telling me exactly where the errors are supposed to happen. I update the function or the function signature accordingly.
I never use Java outside of my job though because I hate all its shortcomings. Rust fits all my use cases right now
@@CottidaeSEAknew there would be this kinda dumbass reply smh. do i rly have to explain how its better? ffs guess i do, then again if yr such a baby when it comes to programming that u need a compiler to hold ur hand every freaking step of the way i guess u wouldnt understand what i actually meant.
@@CottidaeSEAtrust me dude, control flow aint an issue for me lol. im 100% a better programmer than you ever will be. peace.
5:00 The new switch statement is basically a Rust match expression without destruturing or the capability to have guards.
destructuring for switch is planned next. Guards are already in Java 21 (when clause), just omitted in the article discussed here.