Enterprise Java with Spring Boot

Java Language Review

Josh Long
Broadcom
Enterprise Java with Spring Boot

Lesson Description

The "Java Language Review" Lesson is part of the full, Enterprise Java with Spring Boot course featured in this preview video. Here's what you'd learn in this lesson:

Josh reviews some new additions to the Java programming language, including pattern matching, smart switch statements, and records/sealed types. These features make it easier to manage data directly inside the language.

Preview
Close

Transcript from the "Java Language Review" Lesson

[00:00:00]
>> Josh Long: Let's talk about Java itself. Java is, you know, I'm going to be using Java throughout the balance of this course. I'm not sure how many people are familiar with Java. If you've come from another language, then you might have some misconceptions about Java. Java is marked by being sort of the stalwart language of the ecosystem, right.

[00:00:16]
It's the third most popular language these days after arguably JavaScript or Python. Who knows which one is which, but one of those two in the first and the second slot, and then Java is usually the number three. And one of the criticisms people have levied against Java is that it's sort of this anachronistic syntax that doesn't sort of keep up with modern languages.

[00:00:37]
And I would concede to a point that's true. It is not known for having this incredibly expressive syntax, but it is much nicer than I think a lot of people really appreciate. And in particular in the last 10 years, since Java 20, since Java 14, which came out in 2014, there's just been a number.

[00:00:53]
So Java 8 that came out in 2014, there's just been a number of amazing improvements to the language. And one of the biggest single releases was, in my estimation, Java 21, which came out now a couple years ago, right. And in there they supported not just virtual threads, but also something called data oriented programming.

[00:01:08]
So I wanted to talk to you about what data oriented programming is, because it's a different way to think about writing code and writing systems. Okay, so let's create a new project here. I'm going to use just Java 24. That's all I'm doing. I could be using just Java 21 and later, but I'm going to use Java 24, hit enter CD downloads and then there we go.

[00:01:31]
Uao, zip. So briefly, there's a number of features that are introduced in Java 21 and later that change or at least support the new paradigm. Java is an object oriented language, obviously it's functional ish. It's not a pure functional language, obviously, but it's got at least as much claim to that as JavaScript or Python do at this point, right.

[00:01:58]
It can support some idioms there. It's not a pure functional language though. There are side effects everywhere, right. But it's got some of that, but it's not really what it's known for. What's interesting is there's a third paradigm here and the Java language team are calling it data oriented programming.

[00:02:12]
And the idea is that Java has historically thrived in the world of large object oriented systems, right. You remember in the 90s when Java first came out? Remember this year marks 30 years since Java came out. Java 1.0, 30 years of Java. So when it first came out, it was the bee's knees, right?

[00:02:27]
People were on CNN talking about this new language called Java. It was people. Unless you were there, as I was. I was young but I was there. You don't remember the hysteria that surrounded this language. It was like the second coming it was such a big deal and I don't know why.

[00:02:42]
It was just back then the idea of a portable language that can run in bytecode wasn't new. I think it was a lot of a function of marketing. And one of the things that seemed to help buoy the noise that was being made around it was object orientation.

[00:02:57]
Right at the time. Do you remember in the early 90s C was starting to become very popular. You could buy new software and on the box it would say now in object oriented programming, now supporting OOP, right? Like this is a thing. Like I remember WordPerfect, Coral, WordPerfect or Novell were perfect.

[00:03:13]
They actually had some discussion around how they were moving to oop. It's like a huge thing. It was a big deal reusable objects, who cares? Nobody cares. Now you could never like sell your software and say, by the way, it's written using objects. But back then this is a big deal.

[00:03:27]
And I think it's a useful paradigm when you have a large structured code base. Certainly useful when you have large structured code bases with deep hierarchies of abstract types. But increasingly, the way we build systems today is in terms of messages that get sent around over the wire or from one module to another, one component to another.

[00:03:46]
And in that world, objects aren't always. The language hasn't really kept up, it just needs to do better. So in Java 21 they added four new features. Sealed types, pattern matching, records and smart switch. So let's take a look at a simple example. Let's suppose I worked in a highly regulated industry like a financial services one or something like that.

[00:04:10]
And I've got a type here called a loan. Now I want to build a implementation. So I have a secured loan and it implements loan and I have a class, unsecured loan and implements loan. Well, obviously these are two different things and maybe the unsecured loan has some variability.

[00:04:25]
Maybe I have a float for the interest rate, right? Okay, but how can I make this code a little Bit cleaner. Well, first of all, if this is the only state, then maybe this doesn't. If the only state in this unsecured loan is the variable that it passed into the constructor, then maybe I could use something called a record, right?

[00:04:41]
And records are tuples. Other languages call them tuples. But remember, naming is important, right? Java is a nominal language. Everything has a name. Even our functional programming support is nominal. Functional programming, that is to say, they thought about adding fully unstructured lambdas to the language. Like in Kotlin, for example, you can have val, my func int to string equals, and then you do the my int to like that.

[00:05:17]
They thought about doing something like that, which you can do in other languages. They decided against it because what is a int to string? Well, you and I both know what that is. It's a function. But if you're working in a language that makes a big deal out of names, then this just looks like random noise into string, doesn't tell you what it is.

[00:05:33]
So they said, okay, well, everything in Java has to have an assigned type. So you might have a ID converter, which is actually an interface which returns a method given a. Sorry, it returns a tostring or whatever, convert, int, id, that kind of thing, right? And they decided, okay, if you have a class or an interface called ID converter, then you could create a lambda, right?

[00:06:00]
You could say ID converter, ID converter equals that, right? You could do something like that. That's valid Java, but you have to have a name. You have to be able to assign it to a type that you can refer to. And the same is true for these records.

[00:06:14]
Records are tuples but in Java everything has a name. Okay, so this is a tuple, in that the only state that you have, it's a carrier for typed data. But the thing has a name. You can't just do bracket, bracket, int, comma, string, comma, date, comma, boolean, whatever, like you can in, for example, Python.

[00:06:31]
Okay, so here's a record. The records are final by default, right? And the only state that you can pass in comes from these constructors, these component constructors, right? And these are called component fields here. These things right here, this is an interest rate. I could have a string, I could have an int, whatever.

[00:06:49]
I can do all these different things, but they get passed in there. So now I've got two different loans but the problem is I could come along. I don't want to have the Sam Bankman fried problem. I don't want to have backdoor loan, implements loan. And then I just sidestep the validation method.

[00:07:07]
I do a no op on the validation or something like that. You can imagine this having a void validate that nobody listens to, or you just no op, but you stub it out. So what you want to do is make sure that you be very explicit about which things can implement that type.

[00:07:22]
You do that with sealed hierarchies, sealed loan permits, secured loan, and unsecured loan. Okay, now here this is barking at me. It's saying, hey, I can still extend this. Somebody could come along and backdoor this by then creating another. Not secured loan, but extending secured loan. So the language is saying, you're cheating.

[00:07:45]
You can't do this. You need to actually either mark this as final or explicitly permit this third type. So final works. Or if it's a record, it's implicitly final. So now I've got two different types of my code base. I want to create a message to display. I want to create a message to display to the user given a type of loan.

[00:08:06]
So loan. How do I do this? Well, I want to create a message I'll create in a string. I'm going to look at the loan. I'll say if loan instance of secured loan. And the old way would have been to do something like this, you'd have to cast it, cast it down, and you'd say, message equals good job, nice loan.

[00:08:24]
Okay, or you'd say if loan instance of an unsecured loan. Var ul, there you go. Okay, you need to pay more. There you go. So that can kind of work, but this is a little tedious, first of all. Well, down here, like I could put this. I can dereference the field, right.

[00:08:45]
Is a lot, right? There you go. So I can get rid of all that. Okay, so now I've got. I'm dereferencing the instance variable there. I don't actually need the instance variable there. But if I, if I did, it's very tedious to have to do what I just did.

[00:08:55]
This is tedious too, though. So now I'm actually matching the pattern of. Is this type an unsecured loan? If it is, then I want to extract from that pattern an attribute, a value. So I can do that by using this new syntax in Java 21 later to do a pattern match and then an extract.

[00:09:11]
Pattern match, extract, right. So I'm taking a pattern, I'm doing a smart cast downcast to the thing in the scope, but still is this good. It doesn't feel like it's good. And the reason it's not good is because I've only got two cases, right? It can only ever be.

[00:09:26]
We know that it's a secured loan and an unsecured loan, but the compiler doesn't actually stop me from not caring about it, right? That code will still pass, it'll still compile, everything is fine. And yet I've now failed to handle one of the two possible cases there. 50% of my code coverage is missing and the compiler has nothing to offer me here.

[00:09:45]
So how can I write this code in such a way that I get that validation? Well, I can use a smart switch. So smart I can say loan case, secured loan, good job, nice loan, and then there you go. Actually, that wrote it for me. So what it's doing is I've got a switch, I'm doing pattern matching there.

[00:10:03]
I'm not going to use that variable, so I need to do that. I'm extracting out the ul. But the pattern matching is actually smarter than just the type of the thing. You can actually look at the shape of the thing as well. So since I only care about the interest, let me just extract out the interest, in which case I only reference the interest there.

[00:10:22]
I'm saying match this unsecured loan and that it has a component called interest, and if so, extract out within the scope of this, block the float variable into its own variable. So I'm doing pattern matching and extraction. The same thing. Of course what happens if I comment out one of the cases?

[00:10:37]
Well, the compiler is saying, hey, that doesn't cover all possible input values. So I'm getting the compiler to make sure I don't miss something obvious here. Of course, this could just be returned directly. There you go. So there's my pattern matching. I'm using smart switch expressions, I'm using records and sealed types.

[00:10:59]
These things play together to make it very easy to deal with data as first class citizens in the language. Because remember, so much of what we do is dealing with JSON or GRPC or Kafka or RabbitMQ or GraphQL or whatever, right? There's messages coming in from the wire.

[00:11:12]
Our systems are delineated in terms of the API boundaries and the data that they process. The language has to be better at this kind of stuff and I think it's gotten a lot better because of these new features.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Start a 5-Day Free Trial