Gearing up to Java 25: Key Language Features - Venkat Subramaniam
About this talk
In this talk, the speaker discusses the evolution and recent features of Java, highlighting the significant updates introduced in Java 25. They reflect on Java's 30-year journey, noting its initial struggles against languages like C++ and its major feature releases over the years, particularly from Java 8 onwards with functional programming capabilities. The speaker emphasizes the innovative shift towards an agile development cycle that decouples feature development from release timing, allowing for timely integration of completed features. Notably, they introduce the enhanced pattern matching capabilities in Java 25, which now supports primitive types, and the language's ongoing efforts to reduce verbosity and improve ease of use for both new and experienced programmers. They also touch upon Java's adaptability in response to contemporary programming challenges, including AI developments, and express optimism for its future trajectory.
Full transcript
I want to talk about what's really new in Java 25. But before we go into it, let's talk a little bit about the evolution of Java, where we came from, and and where we are today. So, if you look back in time, uh it's it's really fascinating to think about Java has been around for 30 years. Raise your hand if you're older than 30. A few of
us. The rest of you were not even born when Java. So, Java is older than most of us in the room, right? Uh most of you in the room, not us. I'm I'm twice as old as Java. And uh so, essentially, no Well, I'm going to say no other, but let me change my words. No other respectable language, because when I say no language, people say, "What
about JavaScript?" No other respectable language has been around for this long, right? It's phenomenal. So, essentially, when Java came out, the the most popular language was C++. And Java decided to come come down with features that would make programming a lot simpler than C++ was back in time. There was a lot of complexity to C++. But uh when Java came out, and then as Java started uh
progressing, uh Java 1.5, as it was called back then, now we call it as Java 5, uh had a few interesting language features. They had auto boxing, generics, a few other things. Java 6 had no real uh language features at all. Java 7 came much later. And then came Java 8, which was really a lot of changes, especially with functional programming capabilities. Uh if you ever watch
any video from me back in 2010 time frame, I was that guy on the other side of the picket line telling people quit using Java. This is the worst language in the world. You should not use it. I'm not even, you know, exaggerating when I say this. I've saved it away so one day I can document it. I've gotten emails from people that literally started the email
like this, "Venkat, I hate you because you hate Java." So, I used to get hate emails. Uh I didn't get death threats thankfully, right? But it could have eventually gotten there, but finally Java saved me. So, when Java 8 came out, that was the first time I was like, "Wow, this is actually really useful to look at." And then, of course, Java 9 came out uh years
later. And then came Java 10 years later. And they were struggling with this. And the problem was what Oracle, Sun, and then Oracle did is a fundamental mistake every one of us in software development have seen our own companies do. What is that mistake? To announce what will be in a version before any work gets done. Everybody in this room knows that, right? If you tell people
what will be in a version before you write a single line of code, what could possibly go wrong? Everything. So, this was a failure written on its face on day one. So, these developers were sitting and writing code. I'm talking about the developers writing Java, and they were writing code, and some of them would finish their features. Others are still working on it. So, their bosses would
go to them and say, "Hey, we are I have a release scheduled in 3 months. How is it going?" And these people are amazing people. But don't forget, they're amazing people At the end of that is the word people. So they are still people. So when their bosses said, "How's it going?" their response was not very different from what you and I tell our bosses. What do
we we say? It's almost done. Well, the word almost done means 7 years later. So they could never get it done, never release on time because things go very unpredictable. So the folks behind Java in Oracle were sitting and scratching their head. And I think the biggest innovation in Java, this is my personal opinion, the biggest innovation in Java is not the language itself. And to me,
what that is is I'm going to simply say that Java is I'm going to say agile. Now when I say Java is agile, we all have heard about agile development. It's not showing up. Oop, let's see. Can you check why my display is not showing up? That's a good thing to know. Is it showing up now? Awesome, thank you. So so Java is agile. And when I
say agile, you're probably rolling your eyes, right? Oh, we have all seen agile and we know how that badly goes. Well, we do agile development in some weird ways in the industry, but they decided to do something fundamentally different. It's not the 2 weeks, you know, our 1-month sprint cycle we are talking about. They decided to really do something brilliant. And that is they decoupled development from
release. So to me, I would say this is the the genius behind what they did. So, in other words, Java is being released on a 6-month cycle. But, having said that, it's very important to keep in mind that while Java is being released on a 6-month cycle, Java is and very important not be not being uh developed on a 6-month cycle. So, this is extremely important to
keep in mind. So, how how is Java being developed? Every single feature in Java is taking the time it needs to be developed. If you look at one feature in Java 10, which is type inference, that feature took them 5 years to develop. The feature in Java 21, which is virtual threads, it took them 12 years to develop. So, these are not things being done in a
in a sprint. These are things being done with rigor, taking the time it is taking. But, when something is completed, they don't artificially try to coordinate and synchronize that with other features. That's a decoupling. So, when a feature is ready, it can go into production it at the next March or at the next September, whichever is closer. So, there's a train leaving on time. If you're ready
for the train, you get on it. If you're not ready for the train, wait until you're ready and get on the next train. And that was really a fundamental difference in how Java was was, you know, changed in terms of the release cycle, and that started in Java 11. So, since Java 11, they've been making a every 6-month release. In addition to this, one of the things
they also decided to do was to make things as a pre-release. Now, what is the fundamental of Agile development? It's not your stand-up meeting or scrum mastering or that, it's really the feedback loops. How do you get feedback? Well, you do stuff and you ask people to make use of it and that's when you get the feedback from people. So, they do a pre-release. Java requires that
every single feature have at least two pre-releases, at least two pre-releases. However, as an example, in Java 12, they were supposed to introduce a feature called raw string. And when they were about to release it, people were blogging about it, they were talking about it, people were showing demos of this feature called raw string. Two weeks before Java 12 was released, they decided to pull it out.
And all of a sudden, people were surprised. Oh, my gosh, Java 12 was released and raw string is not to be found. Because during the initial offering and people were playing with it, they got really good feedback and they realized that raw strings were going to provide the feature, but it's not going to really help to know where they want to go, which is really they were
going towards what's called the multi-line strength. So, they pulled the feature out, they totally reworked it, and rather than introducing raw string, they introduced this concept of text block in Java 13. So, essentially, this was a lesson from that feedback loop. And just as another example, in the case of Java, I think I can't remember the exact version number, but I think it was like Java 22
or something, they were getting ready to release this new feature called string interpolation. And there were demos about it, people were talking about it, and then as they went through it, they realized this is really not going to work the way they wanted they pulled the plug on it. So Java still doesn't have string templates. On the other hand, structured concurrency was introduced as a pre-release and
in at least two pre-releases. Well, guess what? Structured concurrency in Java 26 just went through pre-release number six. So it's gone through the maximum number of pre-releases so far and they've been just revisiting it and improving it based on feedback they've been receiving. So that is what I mean by Java is agile is they do that agility to the right measure rather than all the hoopla that
we rest of the industry is doing. I think they did a really good job in doing that. So of course there's a lot of exciting features in Java over time, but one of the features in Java that has been evolving is this feature called pattern matching. Now pattern matching is beautiful feature. I really really like pattern matching. I program in multiple different languages and if you ask
me what's one of the features I like among languages, I would say that's pattern This was back in 2017 and as you can kind of imagine right when you say 2017, it's kind of like when you realize that was literally 9 years ago, right? So time flies and I was giving a keynote in Devoxx Belgium and my keynote was titled spearheading the future of programming languages. I
I like ranting as you probably know already. So I wanted to talk about if I want to have a programming language in the future, what do I want to see in a programming language? And it was a somewhat of a frustrating keynote to give. Uh you know, Devoxx Belgium is a large conference. There were about 2,000 people, but what really made me a little nervous was not
the fact there were 2,000 people. What made me nervous was there were two people in the audience that made it special. The first person in the audience was James Gosling, the guy who wrote the most famous language in the world. And I'm talking about what should a programming programming language be in front of the guy who wrote the most popular programming language. The other person in the
room was Brian Goetz, who is the current person who has been writing a lot of features in Java. He's the Java architect. Uh and uh he's the one who is implementing a lot of these features. So, when I finished my keynote, Brian said, "Oh, so you think that's what a language should be?" I said, "Brian, that's my opinion. This is what I want a language to have,
and and these are the things I would be really happy if a language were to have." And he said, "Well, I cannot agree more with you about pattern matching. It is so important. I'm going to give it to you in three installments." I said, "Whoa, wait a minute. What do you mean you're going to give it to me in three installments? I'm curious. Tell me what that
is." And he said, "Well, we're going to take the switch statement. We're going to evolve it into a expression. That's our like first uh step. Then we're going to take the switch expression and start really evolving it into a full-blown pattern matching syntax." Well, he said three installments. I I think he probably meant at least three installments because this has been an installment for the past 9
years, and we've seen so many changes and development. And looks like that's still not done because in Java 25, he gave me the most recent installment of that, right? And now pattern matching not only supports pattern matching against types, it can also do pattern matching for primitive values as well. So, this was a limitation from back in time. We could only deal with some constants and and
you know, enums and so on. But pretty much you can pattern match against numbers, double values, primitive types, just about anything. It's give you gives you that extensible flexibility. So, let's take a look at what can you do now and and where does it take you? I'm going to just kind of switch between language versions here just to illustrate these concepts here. So, I'm going to go
back here and say that I want to output, let's say maturity and I'm going to pass a value of one. So, I'm going to pass a few different values here. So, let's say maturity one, let's say maturity five, let's go ahead and say a 10, let's go ahead and say a a 14, maybe a 18, and maybe a 40. So, let's start with these values and I
want to do something with these different values that you're passing around. So, I'm going to say public, let's say static and I'm going to provide a string and here is my maturity function which takes a age as a value and within this, let's just start with baby steps. I'm going to just take this code and we're going to work with this maturity number. So, what do I
want to do? I can say return a switch right there. I'm going to take the age as the value and I say default and I'm going to simply return an adult right here. So, if I return an adult as a value right there, you can see it says adult for all of those. But then I'm going to say a case of, you know, age. So we could
say in this case int, let's say the age. You know, where we can say age is less than or equal to two, I'm going to say this is a infant, let's say like so. So I'm saying if it's an integer and it's a age and the age is less than or equal to two, we'll classify this as an infant. So when I run this, notice what it
says. It says unexpected type. So unfortunately, what I had to do in the past, in the previous new verse few versions is to say integer and then I have to say if it's a integer type. Now it says integer is not applicable, right, as an int. So then I have to then go back here and say integer, let's say integer {dot} valueOf. And I'm going to convert
that int to a integer and use it. You can see how really not very pleasant that was, right? And you are thinking, why am I doing all of that? Why shouldn't it just say int and be done with it? Well, that's basically Java 21. So I can now go back here and I can change it to Java 25 and I can go back and run that code.
You can see it works just fine. So that's one of the changes introduced in Java 25 is that you can do pattern matching with primitive types. So that removes that clutter, the ceremony, and auto boxing from primitives to the the the you know, classes like integer and you are the wrapper classes, you can use a primitive type straight away. Similarly, I can say if the age is
less than or equal to five, we could say this is a child and you can specify the child. Then you can say if the age is less than or equal to maybe a 13, you could say this is a maybe you could classify this here as a preteen if you will and you can specify that this is a preteen and you can continue processing in a similar
way in here and you can classify this as adult and so on and you can work with it. So, that shows you an idea about how the pattern matching with primitive type has been introduced. Now, having said that uh one of the problems also with Java is we've been hearing this, you know, complaint from people that Java is really verbose, right? Now, the problem though is it's
really about your perspective. Java is verbose is a comment a lot of people make, but there are people who have been using Java for a very long time. Then there are people who have been using Java for a shorter amount of time. Then there are maybe students at the university who have been learning different programming languages. They learn Java, they learn Python and they're like, "Oh my
gosh, why is Java so noisy?" So, one of the things they were really keen on is how can we reduce the verbosity of the language. Now, one of the things to keep in mind is it's important to really understand the perspectives. But when you understand the perspective, then you need to see things from different points of view. Now, this is one of the challenges we often have
to deal with. When you are a designer of things, you need to really think about not what you want to design, you have to think about who is using your product. And in the case of a programming language, programmers are the clients of a programming language. Now, I was mentioning about Java is moving towards reducing verbosity, and in one of the talks I was giving and I
had a person raise my hand. And this person is maybe almost as old as me. It you know, I don't think he's older than me, but he's almost as old as me. And and he I know him. He has done a lot of work. He writes compilers. He has done a lot of work in C++. He raised his hand and said, "I've got a question for you.
I've been using Java for uh you know, since it came out. And before the time of Java, I used to program in C++. So, I've been using Java for so long. I don't get it. We are used to Java. Why do you care that it's verbose? Because after all, we have been very successful with it." And and that's when I I realized what he was saying is
so true. And this is something for us to keep in mind. When you are programming in C++, I often tell people, "Anyone in the room who has programmed in C++?" A few of us, right? Well, you know this when I talk to you, right? If you've done C++ C++ in your life, you can do anything in life, right? Because C++ takes you in and tortures you. And
the minute they let you out, you're ready to deal with anything in the world. So, this person who came from the background of using C++, when you come to use Java, you feel like this was actually a lot easier to use. So, you are coming from having climbed that hill. And now you're downhill, and you're like, "Gosh, this is simple, isn't it?" Then you take these, you
know, people who are just getting introduced to programming, and you ask them to write code, and they're going uphill. So, you are climbing down the hill and you're having a good time, and they're huffing and puffing going up the hill, and they're like, "My gosh, this is really hard." So, it's a perspective, right? Where are they coming from? So, this is one of the reasons why the
developers behind the Java language were asking, "How can we reduce the complexity of this language and reduce the verbosity of the language so it's not only going to do things that the experienced programmers wanted to do, but it's also approachable and accessible to people who are new to the language." That's one thing. The second thing is it's not just new people. There are times when you want
to be able to use a language for different purposes. That is one of the essence of general-purpose language. A general-purpose language, as the name alludes to, is the purpose is very general, which means you can use it for little things, or you can use it for really, really big things as well. So, when you work with a language like Java, if you're developing an enterprise application, you're
writing a reservation system for an airline, and and people have done it. You are using it to run Netflix. Netflix uses Java for a lot of things they do. If you are running a bank, lots of banks are running on Java. Those enterprise systems require very heavyweight lifting. Now, think about it for a minute, right? If you are going to write a little bit of verbose code,
but what you're writing is enormously significant, that verbosity doesn't really pain you as much because you're dealing with enormous complexity, it can do the weightlifting for you. But, there is also other things we do. You know, when I write code, uh my day often involves almost every day I have to do little little little things. I have to write a little script here, a little script there.
I got to do a sequence of things to do things on my system. So, when I write little scripts, you say, "How do you write these scripts?" Well, I cannot write I could not in the past use Java to write those scripts. Why not? Because if I use Java, I have to write the code, I got to compile the code, I got to set the class path,
I got to use a Maven build or a Gradle build, and by the time I get to it, I forgot what I started doing, right? So, this is kind of like saying, "Oh, Venkat, you had to go to the airport, how much time did it take?" "Oh, you know what? It took me an hour and a half to go to the airport." And you're saying, "Did it
bother you?" "No, because the hour and a half was a small part. It took me 38 hours of travel to get here." Well, so in 38 hours, the hour and a half is negligible. But, if I have to go to a city nearby, and if it's a 20-minute flight, but I have to drive for 90 minutes to get there, I'm like, "Why don't we just drive there
directly? There's no point in spending so much time going to the airport. Maybe I'll save some time, especially if it's in the opposite direction I'm going to be flying, right?" So, you really want to ask yourselves, "What's the effort? What's the cost? What's the verbosity?" So, the question is, what if we can write scripts in Java as well? In the meantime, not only can you write scripts
in Ruby and Python and JavaScript and so on, you can write scripts already in languages like Kotlin and Scala. And Kotlin and Scala are languages on the JVM, so the question is, if those languages in the JVM can allow me to write scripts, why shouldn't I be able to do that with Java? So, as it turns out, you can write that code right there, and you can
see the code right there. I can say Java C sample.java, right? And I can compile that code in here. And of course, in this case, I could then say, "Okay, well, that was a preview feature." And and in this case, I can say, "Enable right enable preview." And I can run the feature, compile it obviously in this case, and and I can then and you run it.
I'm going to make this a little bit easier on myself, if you don't mind. So, I'm going to just go back to this code. Let's just, you know, pretend that we want to write something really simple, and I'm going to simply say over here, you know, in this case, you know, a script, right? A running script, let's say. So, I want to just run that script, so
I can say Java C sample.java, and then I can say Java minus class path, the current directory, and then run the sample, and I can do all that work. But as you can see, that's a lot boring. And then if it's a little bit more, you have to go through tooling and all of that, but why should I bother? So, you can see we have the file
sitting right there, and what if I can simply say Java sample.java, and just run [clears throat] it? So, this is one of the changes is that you can run Java code just like it's a script. So, you can write some little code in Java, you don't have to compile the code, you can just execute it. Now, of course, you say, "Hey, but what's happening right now? Did
Java fundamentally turn into a scripting language?" No, not at all. When you run Java, if the file is not a class file, but if the file is a source file, then the Java tool does the compilation behind the scenes, and then executes the compiled bytecode for you. So, it says, "Relax, you don't have to put all that effort. I will take care of that for you." So,
it becomes a lot easier for you. So, that's the very first thing. The second thing is, uh if you're writing So, this is useful for expert programmers, right? These programmers are writing code in Java, but they are these expert programmers say, "Well, I got to write a little script right now." Well, don't worry about it. We will give you this power to do bigger things, but also
the ease to do smaller things as well. So, it really is compatible for a wide variety of things you want to do with this language. Okay, so that is great. But, what if I'm a beginner? Now, you probably have seen this quite a bit. Has anyone in this room ever had to teach Java to somebody? Maybe a cousin, maybe a nephew, maybe a friend's child, right? So,
a few of us have done that, right? So, this person says, "I like to program." And you say, "Ooh, I program in Java." And they say, "Do you really like Java?" You say, "I don't like Java. I love Java, right?" That's what you say. And And they're like, "Ooh, so is Java really hard?" And you tell them, "Oh, no, no, no, no. Java is the simplest language.
It's so easy to learn, so easy to use." So, this person doesn't have a clue where you're going to take them right now. And they say, "Really? I should I be paying attention to?" And And And you have this captive person next to you, right? And you say, "Why don't they teach you Java?" And they're like, "Really? Is Java easy?" "Oh, it's very easy. It's very simple."
And they're like, "Wow, I I like that. Can you teach me right now?" And you say, "No problem." And your your attentive student is sitting next to you. "I want to learn Java," right? They're all geared up. You say, "All right, let's get started." And what's the first thing you do? You say, uh "public." Immediately hand goes up. "Excuse me, what is public?" And you're like, "You
don't need to know that right now." So, they write down public dash no need to know that right now. Got it, right? I can postpone it. Keep going. And then you said class, and they're like, "Excuse me, what's a class?" "You don't need to know that right now." Okay, class no need to know that right now, right? And they're like, "This is very interesting. A language that
teaches you what you need to not not to know, right?" And then you said public class hello world, right? And they're like, "Yes, that's fantastic." And then you put a curly brace around that. And they said, "You know what? That's okay, I can deal with curly brace." And then you public, and they're like, look at the notes, "I don't need to know that right now." And then
you said static. And they're like, "Excuse me, is this also something I don't need to know right now?" And you have completely lost their trust, right? And they're like, "Oh my goodness, I just spent a couple of minutes, and I noted three things I don't need to know need to know right now." They didn't even know what's coming ahead, a main and a string square bracket, right?
And by this time, they're like shaking. My goodness, this is And then they say, "You know the person who was starting trying to teach me Java? They are the most amazing person. Because I had no clue what they were telling me, right?" Well, unfortunately, we lost people in the really the complexity and the verbosity, right? But why go through all of that? So, public static void and
main, and they're like, "What is void, right?" And then string args over here, and then of course you're going to say output, and then you say hello world, and they're like, "My goodness, that's a lot of stuff here for me to go through." And they're a little bit concerned about it as well. So, here is my sample with a hello world. Good that good I'm able to
run it really nicely. That's a lot of work. So, the first question is, what if we were to drop that entirely, and I don't need to be writing the public class if you will, right? So, we remove that part, the public class, and say you don't need that right now and notice the code is still running even though we did not put class and the class name.
Okay, so great, but then why bother about the public? Because that's after all, is that really essential, right? So, we can remove that part as well in here. So, what if I remove that part and and get rid of it? So, let's do something here real quick. Let's go ahead and make this a bit easier on ourselves. So, I want to and I'm going to say this
is going to be java sample.java and I'm going to be running that, right? So, so java and I'm going to be running that code. Here's the hello world. So, we saw how that is displaying hello world in in the background. So, that was great, right? So, we saw that. But then what I say here is why bother with static, right? Does it really help us? Is that
needed? And as you can see, it doesn't care that I didn't put the word static. And then you're like, do I really need the string args? Because after all, if I don't put it, it can still work. So, we didn't add anything. We are removing stuff. How cool that is, especially in the age of AI when we are interested in writing stuff. This is going in the
opposite direction, isn't it? So, this is one of the words of you know, Antonio is is buried and he said perfection is achieved not when you have nothing more to add but when you have nothing more to remove. This is a very important thing to remember. It's not about what you can add. It's not about, oh, how is it looking? Oh, I have nothing more to add.
That is direction of complexity. But a perfection is achieved, he says, when you have nothing more to remove. So, what is it that I can do? Distill it down to minimalism, so I don't have anything more to remove. We're not done yet, right? You say, "All right, that's great so far, but why do I care about system.out.println?" That's a lot, isn't it? So, I o.println and I
can simply say I want to just print stuff right there. And we can simply say a percent S, maybe we can say in this case a dot in this case formatted, and then we can say a name, but what in the world is a name? Where is that coming from? We can say name is equal to io.readline, and we can say in this case could say, you
know, what's let's say what's your name, and we can ask for the name of this person in here, if you will. So, essentially in this case, you can ask, "What's your name?" I say, you know, "Joe," and it says, "Hello, Joe." So, essentially the idea here is that you can pretty much distill this to a minimum amount of code, so you can ease into it. So, you
can, yes, do all the things you need to do. If you're developing a larger system, sure, start bringing in classes and methods and public and private and protected, but you can ease into it rather than being hit on the face at the very first step you take. So, this gives an opportunity for you to incrementally develop, rather than having to just go full-blown into it. And I
think at this point, we will have a better set of trusting students with us, right? Because you're like, "You want to learn Java?" You say, "Let's write a main function." "What is a main?" "Oh, main is like the main thing. It's a starting point. Okay, I got it. You can actually tell them what it is rather than saying that's not something you need to know right now.
It's easy to communicate. And then you can slowly introduce them to taking arguments and command line arguments, and then you can incrementally walk them through, and that becomes a nice way to make progress into it as well. So, you can run this really with this and incrementally build into it, and we saw how you can progress along and keep adding more complexities into it. Now, up to
this point we saw a few different interesting features, but going back to this, one of the things we often do is in Java we have to do imports. Now, this is a fundamental way to understand. An import is not required. Import is not required if you specify the full name of a class, but specifying a full name of a class is rather verbose, and it's going to
make code really hard to read, hard to maintain. But, import doesn't have anything to do with references. If you don't have something in your class path or in your module path, putting an import is not going to help. So, an import is for for the compiler to know what you're referring to, and the class path is for your runtime and the compiler to know where to get
stuff from in terms of where the binaries are. So, essentially in this case, you could you could do something like this, right? So, I want to write an HTTP, let's say, client, and I say HTTP client is equal to, let's say, null, and I'm going to output, let's say, using HTTP client. Now, in this particular case, if I try to run this code, it says, "Simple HTTP
client, I don't know what you're talking about, right?" Well, it turns out I don't need to do anything special to bring in HTTP client because it's already part of uh the the the set of binaries it's going to bring in in rt.jar or depending on the modules that you have available. But, I do still have to perform an import, right? So, I'm going to say import java.net.http.star
and I want to bring in the particular import in this case. Oh, it's it doesn't exist. Where is this HTTP uh client coming from? Let's take a look at it. So, this is going to be coming from the uh you know, java. Let's let's look up for it. So, where is HTTP client uh you know, Java class that's coming from? And that's there's HTTP client. Let's go
into the package and take a look at where that package is located. And that's java.net.http and and silly me, I should know this better. Uh this should be a lower case, right? So, essentially, that is basically where it's coming from. So, we found where that is located. But, in this particular example, as you can see, I had to go find the exact package where that is located.
But, you can say, "Oh, Venkat, but you have IDEs that can do this for you." Sure. But, when in again, there's no real standard here and and to me, this this is a little bit tricky because there is I can't I can't tell you one way or the other which is better. It depends on your coding standards, your your team's um you know, uh uh decision as
to what to do. I have certain clients, they do not permit me at all to put a star. That is their requirement. They want to be able to list, if you will, every single uh class explicitly before you can use it. Well, that's fine. I respect that. They want to be able to see it and clearly see where it is coming from. Some people use a star.
But, when you start using this, if you have multiple packages you're using from the same module, then you got to list every one of them. Well, if you're using modules, why not simply say, rather than this, why not simply say import module, if you will, and and module, and in this case, I'm going to say the module I want to use is what our module is going
to come from. So, so where is that module again, right? to know which module it's coming from. Once again, let's go back here and say HTTP, you know, Java class. Let's see if it gives us the module information in here. So, this is going to come from java.net.http, the same module, if you will. So, I can say this is a dot HTTP. Turns out that's the name
of the module, as well. But, I'm using the import module rather than using the import of the package, if you will. So, the moral of the story here is, you can not only import classes, but it can import modules, as well. What's the difference? If you import a module, it automatically references all the packages in that module. Again, this is where I would say, I'm not still
convinced whether this is a good idea or a bad idea, right? So, your mileage may vary, depending on how, you know, comfortable you are with it. But, on the other hand, let's say I'm interested in a date over here is equal to null. And obviously, date is a old stuff, maybe you don't want to use the date, but this is just an example to illustrate the point.
So, if I do this, it says I cannot find the symbol, where is the date? So, I am going to say, all right, let's do an import module, and java.base, and I'm going to bring the module base, and it says using date. Well, that's great so far, but what if you by a way of using other things, you also have a java.sql module that you bring in
as well. Now, in this case there's an ambiguity. It says, "Gosh, I can see a SQL date and a Java util date. Which one are you referring to?" So, if you get into that situation, you can always resolve it by saying, "I really meant the Java SQL date." And you can reduce reduce that ambiguity as well. Now, I would say this is interesting, but you need to
use use your judgment whether this is something you want to use or not. If you ask me, "What do you think? Should I use the module import or not?" My honest answer is, you know, play with it, see how this goes, see if it leads to confusion in your teams. If it is, fall back to what we did before. If it doesn't, maybe you can start using
the modules. Sometimes it may help you when you have your own internal modules, just referring to them may make it easier without causing confusion. That could be a good place to use the module import. So, that is something you can do as well in terms providing the import to the entire module. Um so, the last thing I want to show you here is a problem we've been
having for a very long time in Java, and it finally gives an opportunity for us to fix the problem and move forward. So, so what is the problem first of all? Well, as it turns out, there are two separate problems we need to talk about. So, let's take an example to understand these two separately. So, I have a base right there, and I have a class which
is derived, which extends from the base class like so. So, in this case let's say a private int, let's say value, and then I'm going to say a public base, and int, you know, a value, and I'm going to simply say value equal to a value, right? So, we have that particular value given to us. Now, in this case, I want to write a constructor for the
derived. So, I'm going to say public derived, and this takes a value in like so, right? And then I'm a super, and I'm going to pass the value like so, and value let's say times 10, which is fine, right? You can do it like this. And in this case, I can say, you know, a derived, you can say is equal to new derived with a value of
10, and output let's say, you know, you know, let's say created, right? For now. So, when I run this code, it says created, not a problem. However, maybe I realize that this is a very simple arithmetic, right? But just for a moment, imagine this is a little bit more complex than what you see to to be really little bit trivial. So, wouldn't it be nice if you
were to say bar, maybe, you know, computed is equal to value, let's say, in this case, right? Value times 10, and then you can pass over here the computed value like so, right? So, you can just do the computation and then send the value to it. What does it say? Call to super must be the first statement in the constructor. Now, look at this and say, well,
duh, that's two restriction for no real benefit. Now, obviously, there is a reason why this exist. And and what is the reason? They want to make sure you don't call any methods on the object until the construction of it has been completed. So, there is a good reason behind it. However, in implementing that constraint, they did an overreach of the enforcement. And they said, "Because you should
not do a bad thing, we will not allow you to do anything." Right? And that is very restrictive. There are times when you may have to do a bit of a complicated logic, but if you're not able to do that, that really places a constraint on what you do. So, typically, that becomes really hard to implement. So, what are you going to do? You're probably going to
say a private, let's say, static, and then in let's say int compute Excuse me, where the compute takes a and returns that computation you are interested in. And maybe you will come and try this and say, "Can I call compute right here and and pass the value to it and do the work?" And the answer is yes. But how do you feel when you finish that? You
are kind of scratching your head and saying, "I feel dirty because I had to work around the compiler's limitation. This should have been a lot easier to do." And so, that's kind of the limitations we've been hitting all along, if you will. So, the question is, how can we accomplish that is the question. So, the answer to that question really is that, as you can see, that
code did not work a minute ago. I run it now and has no problem. Why? In Java 25, you are allowed to call things before the call to the super constructor. However, what you're not allowed to do is this.value equal to something that is not allowed. It says, "Value has private access in base. You cannot call that. Okay, that's in base. What if I said a private
int stuff and I want to call this one and say, this is going to be this.stuff equal to four and I'm setting that value. Well, you are able to call that this part. What if I try to call a function on this, right? So, I'm going to call a function foo and let's say this is a public void foo. I want to implement here on that object.
It says you cannot call that before the super constructor. So, there's restrictions still. So, while you can do things here, you cannot call into your own object at this point. But on the other hand, you can say output, uh you know, uh uh you can say derived uh derives uh let's say a constructor uh called and you can specify that as well, not a problem. So, you
can do calls that do not affect the object in any way and after the super call, you can do things that affect the object afterwards. So, that is permitted. Okay, so that is great so far. We saw how we can make use of that. So, that that's nice. But let's go back again to one more example here, if you will. So, in this case, I have a
base constructor and in the base constructor, I'm going to say uh calling uh base's constructor, right? So, here we go, calling base's constructor. Now, this will not work in the older version of Java, but we don't have to worry about that right now. But I'm going to go back and say uh super. Right there, we are calling the super and maybe, you know, I'll just keep this
here a private int value and I want to call this and pass the value uh to the base, so we'll say value. So, this is passing the data to the base and then I'm going to say output, let's say uh derives a constructor, let's say uh called, right? So, we called the derives constructor at this point and it displays calling base constructor, derived's constructor called, created. So
far, so good. But, I'm going to go back here and say a public, let's say a private, let's say a string, let's say info. And so, then I say here a comma string, uh let's say message, right? So, the info, and I'm going to then say this.info equal to the info. So, I'm setting info into the object. So, once I set the info to the object, uh
what do I want to do? I want to be able to provide a public, let's say a string get info, and this simply says return info and returns it, as you can see. We'll take baby steps towards this, right? So, we have that in So, now I'm going to say, uh you know, hello is a little info I want to pass to it and execute it. So,
then uh we can say output when finally here. So, we can say output uh derived.getinfo, and that's going to tell us hello. So, all that is working fine. But, let's go back here and say that in the get info, I'm going to say a dot to upper case and convert it to upper case and return it, right? So, I want to return it in upper case, as
you can see right there. All that is good so far. But, I want to do something a little different. I want to go to the base constructor, and I'm going to provide a public string get info, and this is going to return just an empty string for now. So, you can see there's a get info in the base, there's a get info in the derived, right? In
two places. And in the base constructor, I'm going to call get info, and I'm going to say calling base constructor, and then I call the get info right there. So, now um instead of calling it get info, sometimes you could call it as a init. You're initializing something. Whatever that you do, doesn't matter, right? So, you have some function you're calling right there. So, let's go through
this code. Base has a value. Its constructor takes a value. It says, "Calling base constructor." It then says, "Value equal to a value that's given." It calls the get info. And which returns an empty string. Then you have a derived which extends from base. Has a private info uh string. It has a constructor that takes two parameters. Calls super and passes the value to the base. And
then says, "Derived constructor called." And says, "Info equal to the info." Sets the value. And then finally get info returns an uppercase. And then we're going to run this code. Uh does anyone want to take a guess? What is this code going to produce as an output? What's going to happen when we run this code? Any guess? Yeah, please. A little bit? A lower caps? Not quite
true, but good try. Thanks for Much more severe. What was that again? It's still >> [clears throat] >> Line number he wants. Line number, folks. Let's give him line number. All right, go for it. Yeah. >> When the uh the code is at the line number nine. >> Yep. >> Um it's actually dealing with the object >> Yeah. >> of the derived. >> Mhm. >> But the
handle I'm not aware what should be the handle uh because if the handle is uh saying that it should pick up the la uh the code number line number 12 that it is you're very very very very close to the So, he's he's he's almost at the seat. He's just ready to sit down on the hit the problem. So, let's walk through what he said. He nailed
it. You are calling the derived's that's calling the base's constructor the base's constructor is calling get but the object type is not base the object type is derived because of polymorphism. It doesn't call the get info here, but it calls the get info in the derived. When it calls the get info in the derived, it says info.toUpperCase. What is info at that moment? Null. Null. So, what
do you get out of this? Your friendly neighborhood null pointer exception. Anyone likes null pointer exception? Do you go home carrying null pointer exception with you? And your family is like, "What is that?" "That's my null pointer exception I got at work today, right?" You don't do that, right? You We hate null pointer exceptions. So, when you run this code, you got that NPE, null pointer exception.
Bingo, right? So, this is an annoying problem. The problem here is that in this case, you are get info is polymorphic and you're like, "Gosh, I wish I had set the values property before I had called the constructor of the super." So, how do we fix that problem? Well, what if we take this up here, right? What if we take this from here to up here? So,
if I run the code, it says call to Because you're not allowed to call something before, right? That's the way Java was. But, it doesn't mean that's the way Java is. So, I just switched to Java 25 and I run the code and it's fine right now. So, this is the reason they fixed it. So, they said there are times when you need to call polymorphically some
functions and if it is not initialized properly, it's going to fail and there's no real easy way to fix this problem. You're doomed if it works one way, you're doomed if it works another way, right? And so, they're like, but what is causing this problem? Fundamentally, what's causing this problem is we need to initialize certain states before we run the constructor. Now, what do you do in
languages like C++ and and C#, you normally in the constructor, you put a colon right about there. And then you put some code in the colon. That gets executed before the constructor is even called. But, Java doesn't have that capability. This somewhat introduces that capability. So, before the super, now in Java 25, before the call to super, you can do some work. But, what you do there
is still restricted. But, the restriction is a valid restriction now and not some arbitrary restriction that they once had. So, it's evolved in the right direction to make things a lot better, a lot lot easier as you can see. this is a lot of these changes are very fundamental to addressing the language for the benefit of either a newcomer to the language or for an experienced programmer
but who often struggles to do simpler things with the language or uh struggles to do things that will make their life better but that the language has been too restrictive on them. So, that is the direction in which language has been moving is to really make it much more pleasant experience for others to use. Of course, until Java 25, a lot of new features have been added
in the past few versions but this has been more focused on making the language expressive, more elegant, and easier to work with as well. Now, having given this, you you you ask the question uh what's what is it done? Uh I would say it just started, right? It just feels like that. Um very few languages in the world have survived for 30 years. Uh generally, languages survived
in terms of popularity, right? When you say survived, there's an old dude that like I still write COBOL code. I'm like, thank you for doing it so the rest of us don't have to do it. But the point really is popularity-wise, languages were popular for 10 years in the past. And and they take a peak and they they plateau and then 10 years later, not many people
want to really get excited about it, right? Uh very few languages have been running for this long. Uh JavaScript has is is is 30 years old almost and and Java has been running that long. So, this is very very different from what has been before in the new in if you go to previous generation of programmers and you talk about it, uh languages had a lifetime like
dog life, right? So, they don't last for too long. Uh and then you're like, I used to use this language but it's gone, right? And we only talk about admire it. But this has gone really really far into it, pretty pretty amazing in terms of its capability. Uh what that means is the language is evolving constantly to provide for the future. Now, you can imagine 30 years
ago what we expected from a language is very different from what we expect from a language today. So, they are really trying to address the current times and how it can be for what we want to do now. As an example, a lot of people are writing code related to AI. Java has evolved substantially to support AI. So, for example, they're introducing things like value types, for
example, and a lot of things related to performance improvements so that it can be faster and more optimized when it does AI-related code. So, a lot of those changes are happening as Java is moving forward. So, this is very exciting time. If you are committed to using Java, there's a lot the language is offering, but it's also continuing to evolve as well. And it's no no longer
that language that was stagnant once upon a time and I was complaining about it. And and for me to really stand here and praise the language, I think it deserves every bit of it now as it deserved my complaints decades ago, but it definitely has gone in the right direction. Thanks for joining. Hope that was useful. Thank you. >> [music]
More from this event
See all 126 talks →
AI Is Not the Risk. Architectural Drift Is - Sunil Kalkunte
17:39
Breaking the Monolith: Tesco’s Journey to Federated GraphQL with xAPI - Vishwas Chandrashekar
29:13
A Practical Introduction to LangChain4j - Venkat Subramaniam
1:01:28
Beyond the AI Models: How Lowe’s is Building the Store That Knows - Swaroop Shivaram
13:59