[ERROR NullPointerException] Null safety-? vs manually verify that the object is null (Redundant concept)

@broot

Just for technical correctness, this is not true at all.

I understand what you’re saying, and technically I’m aware of that, but I think it works as an analogy.

(Though technically it would depend on the backend: lately I use the JavaScript backend more than Java, and I don’t think Kotlin/JS represents String as a Java String.)

To teach me you would first need a certification or a master’s degree.

In fact, I have both a Master’s Degree and a doctorate, but since you don’t consider me worth your attention, I won’t waste your time.

Per quanto vale, non sei nemmeno l’unico poliglotto in questi parti.

As I tried to illustrate most of that kind of null checks should be kept at the application boundary and in a (well-designed) large project the application boundary should be a minor part of the application. And even in the boundary code we can often avoid explicit null checks. If we for example parse a JSON string into an object containing non-nullable properties, we would probable catch some kind of ParsingException instead of null-checking each individual field. This would be the similar to when the JSON contains a string value where an integer is expected.

Yes, Kotlin implements its own style for some null checks. If a lot of experienced developers really like Kotlin’s style, maybe it does have some value. Personally I think the operators ?. and ?:, together with the rest of Kotlin’s style, help make the code more readable and expressive. I recommend you spend some more time writing and reading Kotlin code before deciding the style is no good.

As for arguing that those operators are redundant, the same could be said for a lot of constructs in a lot of languages. In Java, the ternary operator is redundant because you can achieve the same using if/else. For loops are redundant because you achieve the same with while loops. Even lambdas are redundant because you can use interfaces and classes. The point is that these construct are only redundant from a functional point of view but when it comes to readability and expressiveness they add a lot of value. In my opinion, the same is true for ?. and ?:.

And finally your first point:

Null pointers do appear in Kotlin (because we can have nullable types), but NullPointerExceptions don’t thanks to the null safety features (as described by a lot of other replies in this thread), unless you use the !! operator, which almost always is discouraged.

3 Likes

You are not the only one, and Kotlin isn’t the only language to do so.

C# added the ?. and ??= operator in C# 6 and 8
Typescript added the ?. and ?? operator in 3.7
Python added the ?. and ?? (and others) operator in 3.8
Even JavaScript has the ?. and ?? operators in ES2020

All of these are languages that absolutely dominate the industry, and there’s many more (here’s a list and another).

I’m hardly an authority on them matter, but I can link you to the motivations of other languages:

  • # PEP 505 – None-aware operators
    This one actually directly answers your question, conciseness seems to be the main motivator.

  • Optional Chaining for JavaScript
    This page contains links to a bunch of committee discussions about the null safe operators in JS. A lot of it is about JS-specific problems with the feature, but it does motivate the reason to add those operators despite the hardships.

I’m certain there’s many more proposals, I just found these two after a quick google search. All that to say that there’s a a bunch of documentation on this discussion you can search for yourself if you find these discussions unconvincing.

4 Likes

Why does Java need Optional in the library when it already has null in the language?

2 Likes

As far as I can tell, the main reasons for Optional in Java are:

  1. Forcing checks and safe dereferencing.

  2. Similarity to some functional languages.

  3. Ability to represent more than one kind of missing value, e.g.: uninitialised, unknown, unavailable, error, not applicable, empty… (Null could represent one kind, an empty Optional a second kind, and you can nest Optionals if you need more, though of course it gets very unwieldy and there are usually better ways.)

I suspect that in practice that first reason is the main one. But of course, that reason doesn’t apply in Kotlin, where nulls themselves are handled safely with compiler-mandated checking and safe dereferencing. So you might well think that in Kotlin there’s little point in using Optional, with its longwinded syntax and runtime overhead, when nulls are simpler, safer, and more widely used and understood!

3 Likes

Drakgoku, it seems that you continuously ignore substantial arguments people kindly try to communicate. Instead you react with aggression and cherry-pick sentences from other’s posts. So I will answer in a style I believe you find more appropriate. Your posts are bullsh*t and you’ve no idea what you’re talking about. I’ve never seen a NPE in a kotlin application, unless I used !! somewhere or interacted with a Java code in an unsafe way. Which is what you did, and you got NPE. Congra-f*cking-lations.

4 Likes

Kotlin gives you tools to deal with nulls better. Within certain bounds using these tools ensures you won’t get NPEs. Of course there a limits to these guarantees.

  • The ‘!!’ is a operate that basically says “I, the programmer, know for certain this value can’t be null even if the compiler can’t prove it”. It’s explicitly an escape hatch from null safety and therefore it’s expected that you can get NPEs when you use it incorrectly. Complaining about this is exactly like using JNI from Java and then complaining “how can I get memory corruption when Java is supposed to be a memory safe environment”.

  • If you think that Kotlin is a language without nulls then you think wrong. That’s not the goal. The goal is to make it possible for the programmer to be sure that null values are properly handled in his program.

  • In your date example you are passing null to java code and that’s the best illustration for what Kotlin offers. When you see the function format(date) it’s impossible to know whether it will handle null or throw NPE unless you read the source code. This is a limitation of Java that “infects” Kotlin because the Kotlin Devs want to be able to call Java code with very little friction. But the makers of Kotlin are even working on this problem by utilizing null-ity information from annotations in java code and also (afaik) by adding this information themselves for the standard library.

1 Like

Ok … however, as I have reiterated for the umpteenth time, you have another concept that can be solved by another concept.

While christofferberg79 was clever in arguing

You are right. But “adding one more concept”, when there are already many ways, does not seem very useful. You can see it efficiently, for others it is not efficient. I prefer to handle nulls anyway. So in the future, it is “unlikely” that you will have bugs.
A good programmer should understand where NPEs are produced. Those who are not good programmers, well … I can tell you little, good luck.

I summed it up in one line “A good programmer should …”

Well, arguing this, knowing that there are many programming languages ​​that have memory leaks, is a cheap blow. Java is getting better at this point.

If we look at the nix-united.com page
Have:


"The table above shows the average results of the massive tests provided by enthusiastic engineer Jakub Anioła. He has done much work. All test processes are described in a series of Medium posts dedicated to comparing the performance of Kotlin vs. Java. If you are interested in which methods and tests I have conducted and the results, you should read his posts."
With all due respect to this person and the work he has done, such comparison of technologies has only scientific value. It doesn’t reflect the actual performance each programming language will show when solving real-life tasks. Also, the differences between Java vs Kotlin are so minor that it’s unlikely your business software will face anything in which the differences will be meaningful.
Returning to the main topic, Java isn’t inferior to its young opponent and even precedes Kotlin in most tests, as the table shows. This means that performance is not the reason why more and more developers prefer Kotlin over Java."

Other table

If we look at:


"The above charts show that for five out of six cases, Kotlin produces more statements and creates more allocations. Java generated bytecode has more statements and allocations only in one benchmark, namely Fannkuch Redux. Based on that, we can assume that JVM compiler produces fewer allocations and shorter bytecode while compiling the Java code instead of Kotlin. "

If we look at:
https://miro.medium.com/max/480/0*SjrtjUNKB1rW4SbO
For clean builds with no Gradle daemon, Java compiles 17% faster than Kotlin.

If we look at:
https://miro.medium.com/max/480/0*6a9Jt7H3J_QEndV4
Ten consecutive clean builds with the Gradle daemon running
As you can see, the first run takes about the same amount of time as without the daemon, but subsequent runs increase in performance until the fourth run. In this scenario, it’s more useful to look at the average build time after the third run, where the daemon is warmed up. For the warm runs, the average time for doing a clean build in Java is 14.1 seconds, while Kotlin clocks in at 16.5 seconds: a 13% increase.

If you look at the popularity trends on Java or Kotlin, you can ask google yourself and it will tell you that they are more interested in Java.
https://trends.google.com/trends/explore?geo=US&q=%2Fm%2F07sbkfb,%2Fm%2F0_lcrx4

If we go to scand.com, we can see
https://scand.com/wp-content/uploads/2019/05/bp060-1-differences.jpg
They tell us:
“Literally, the developers prefer Kotlin for it’s easiness of coding and a way to make the application run almost as smooth as on Java.”

According to Google, the trends are focused on Java. There may be programmers who see performance as a priority, but not usually.

Kotlin vs Java: Performance Drill down & Which to choose | by John Korly | Medium.
For the warm runs, the average time for doing a clean build in Java is 14.1 seconds, while Kotlin clocks in at 16.5 seconds: a 13% increase. For clean builds with the Gradle daemon warmed up, Java compiles 13% faster than Kotlin. Kotlin is catching up to Java, but is still trailing behind

Going back to what you told me, if we talk about performance, I can buy you "that sometimes Kotlin has a better performance of 5 - 8% than Java and other cases Java has better performance. But nothing more.

I summed it up in one line “A good programmer should …”

This is not correct. That variable can be assigned to a service and that service return objects of type data, including a null (as I showed) and all that with the null safety. (If you’re going to look at the source code trying to find nulls, good luck.). The important thing is not to look and find nulls in the code, the important thing is to understand what the services do and what type of data could arrive or not arrive (something elementary).

If something in Kotlin (which in many cases starts with Java) goes wrong, we blame Java. How could it not have crossed my mind? Instead of Kotlin being totally independent from Java and doing its own functionality. “Oh right, it’s better to blame Java.”

I think things are getting a bit off track.
We are not talking about performance or who is better than who or what one does that the other does not.

We are talking about a concept. It is productive not to go out of that scope, why if not, this publication will not be able to help future.

I put the title again in case we got lost.
[ERROR NullPointerException] Null safety-? vs manually verify that the object is null (Redundant concept).

A good programmer should never introduce memory leaks…

Strong typing is also useless, because a good programmer should know types of objects and access their members correctly.

1 Like

Today I have 5 - 10 free minutes and I am going to give myself the luxury of answering “fools” I said “fools”? Yes, we confirm that I said “fools” or, in other words, someone who has some mental deficiency.
This will not happen normally. (only when I see a lot of stupid).

Did you want my attention? Don’t worry, give me 1 min to put you on your “fucking” site.

To begin with, if you never got any NPE it means, that you are learning, or that you have never programmed seriously or simply your code does not do business functionality, in other words your code is from a newbie.

In images 4 and 6 of my first post I did not add the operator “!!” but i got an error. Do you know why ?, because in 5-8h I learned its maximum expression in Kotlin and how to make it jump (Throw errors out of place). Whereas in your case, you program simple things and you don’t have much programming idea. Have you seen the difference?

It is important that you understand that you do not have much idea of ​​programming if you make this argument to me. I hope you do well at work, since you don’t show much cunning.

In this life there are many types of people, those who do not listen, those who make mistakes, those who speak without being right … and those I like the most, stupid.

Before attacking saying nonsense, find out and contribute something positive instead of saying nonsense. Investing my time with you is throwing it away and my time is much more valuable than your own life. (It is a concept that few understand)

For those who felt offended: “There must be moderators who do not allow people with little reason and above all who feel with the power to insult”

Or that you use a language which supports null safety :wink:

What is the point of asking other people about their opinion if then you just deny the information they provide to you?

1 Like

It’s very useful to me. Maybe I’m just not “good” enough but I like my code to be concise and to the point. What I don’t like is to have to litter my code with if(val != null) especially when the if construct isn’t an expression.

val dateString = formater.format(date ?: Date(0))

vs 

String dateString;
if( date != null) {
   dateString = formater.format(date);
} else {
   dateString = formater.format(new Date(0));
}

Like I am said maybe I am just not good so I prefer Kotlin where I can see with one glance whats going on. I also don’t like to have to forever keep track of which values I already checked for null and which I haven’t when the compiler can do that for me.

That’s just the null check which is already way more ergonomic than Java’s but what you can actually not do in Java is force an argument to your function to be not-null like you can in Kotlin:

fun foo(bar : String) : Boolean = bar == "foo"

In my own code this guarantees that the function can never be called with a null argument so I simply don’t have to do null checks. Btw, it also guarantees that the return value of the function will never be nulls so I already saved myself 12 lines vs the “check everything” Java code.

I don’t understand how this relates to what I said. The !! is just there for the cases where the compiler doesn’t understand that a value can’t be null such as here:

if( map.containsKey("key")) {
    map.get("key")!! // in most normal cases the value from the map can't be null here
}

It’s not about leaks. It’s about guarantees. “As long as you stay within Kotlin and don’t use !! you’ll not get NPEs” is equivalent to “As long as you stay in Java and don’t use JNI you’ll never get memory corruption.”

I am not surprised that Kotlin allocates more and that the Kotlin compiler is slower. That’s fine for me. Runtime performance seems to be mostly the same. I never said I use Kotlin because it’s faster than Java.

I can handle nulls in Java but it’s a complete pain. All this defensive biolerplate and no compiler support. I have to look inside every function I want to use to see if it can return null. In Kotlin I mostly don’t have to think about it as the language supports me in writing null-safe code.

I don’t understand this at all because your English is really unidomatic here. “Service” can not return null in Kotlin if it’s function is specified as not-null. Java function can take null or return null and the only way to know if they do is to look at their code (or, sometimes it’s mentioned in their docs). I can “know what services do” and still not know if there might be conditions where it would return null.

I blame Java here because it is Javas fault. You’d also get an NPE in Clojure or Groovy or Scala exactly because the JAVA API is not null safe in this example. Kotlin can not control how the Java Standard Lib works but even so Jetbrains are doing their best to mitigate this incongruity by adding null-safety information after the fact. You could also use Kotlin standalone and never see an NPE but it wouldn’t be nearly as useful so this is not a practical road to take. At least with Kotlin I can “firewall” the core of my app from the null-safety issues the underlying platforms might have.

1 Like

Based on your code I allowed myself to make a modification to see it in one line.

Based on the java code (we can control what we want with the ternary operator) and even assign it. (So we can know or detect all kinds of errors)

There are many more fancy ways, but I took the simplest form.
The problem that Java is difficult I think is in teaching. Normally teachers only teach up to Java 6. Then being self-taught comes out of yourself. That is why it is sometimes easy to criticize a language from 2006. That expression is from 2006.

To conclude, so as not to create more discussion.

Null Safety you use it both to shorten the writing, and to control the nulls. I think it’s fine. But I will not follow that “concept”.

In my case, I prefer to do it manually. It is a long story but I am going to tell it and summarize it for you.

Why? In 2014-2016, when I was doing C / C ++ in unreal engine with handling with many APIs / blueprints, I noticed there were general problems. Sometimes we had nulls and we didn’t know what type it was.
In that case we went to look for good practices, the recommended thing is to make a generic class, a custom of exceptions and with predicates that would tell us what type the error was. (With this method, the headaches passed quickly and any errors were quick and easy to fix.) Because we knew the problem and the cause without looking at the code.

In 2015-2021 when I was doing Android and also Java EE, I realized that my team always performed good practices, that is, a generic class, with its custom exceptions etc.

Now, if you tell me that you don’t want to handle exceptions, that’s fine with me. In my case, whenever I can I will use it, either in (BBDD, Files …). It is highly unlikely that I will get such an error and if it occurs I will know (not from the code) if not from the custom error message.

I guess this is like everything. Use what you like best. I prefer to use good practices.

Seeing the “NS with?” Reminded me that all Kotliners good practices are going to disappear. (Because the NS intends to replace the null control, which we already have how to control them, hence the duplicate concept … I hope that someone from the entire post of the 500 people, at least 1 has reached this conclusion) I do not think that In Spain we have a better programming culture than in the US … I hope so.

Well, I know PHP people who don’t know how to program in any language other than PHP, (and they don’t know how to do a good architecture, both in OOP and in general.)
Then sometimes when I see codes, it hits my heart. You have heard the motto of “This code has been developed by … without documentation, without good architecture … I do not touch this”.

It is important for all those who want to contribute something positive next for the future, it will surely be of great help.

Sure you can use ternary operator for null checks but even that is cumbersome compare to the power of ? especially when you chain a few calls together. Here is a nice example from one of my projects. It’s leveraging null-safety to really tersely go through all the cases. If you have the patience, convert this to Java / ternary and see how it looks:

private fun findOrCreateArtikelId(etsyTransaction : Transaction, etsyListing: Listing) : Int {
        return (artikelDao.findByEtsyId(etsyListing.listingId.toLong())
                ?: etsyListing.sku.firstOrNull()?.toIntOrNull()?.let { artikelDao.findByOnlineshopId(it) }
                ?: artikelDao.findByName(etsyTransaction.title.etsyTitleToArtikelName()).firstOrNull()
                ?: artikelDao.insert(artikelFromEtsyListing(etsyListing))).id!!
    }

(‘Artikel’ means product)

I don’t really get what this amounts to, maybe you have an example. With Kotlin I have null-safety inbuilt and so I don’t really need to spend any time on implementing “good practices”. The Kotlin language is the good practice.

Actually, ‘we’ don’t know how to control null that well that’s why people call it the billion dollar mistake. It bothers Java programmers so much that they are going with an annotation-based scheme that doesn’t even do half of what Kotlin does. I don’t agree that it’s a “duplicate” concept. You don’t have non-nullable types in Java that get checked by the compiler. You don’t have safe-call operator in Java. How can it be duplicate if it can does so much more?

Have you considered that you might be wrong about this?

I just had dinner and I find myself an easy challenge. I think an expression from 2006 will be able to do it.

I did not use optionals, nor annotations, nor custom generics, nor did I use the new functionalities of for each detecting nulls in the same line … Anyway, I think that an expression from 2006 can fight against a Kotlin example from 2021
Now with Java 15 (you do a lot more nice things)

Nor am I here as a converter. Do your own tests. So this is going to be very latest code conversion. You can do it yourself.

A scenario that is completely unthinkable in Java and Kotlin (or any OOP language). The design pattern does not translate to languages that have a robust type system.

In 2015-2021 when I was doing Android and also Java EE, I realized that my team always performed good practices, that is, a generic class, with its custom exceptions etc.

I’m not sure how this relates to null safety. Nowadays, the preferred way to deal with nulls in Java is returning Optional instead. If Android ever moves to support a modern version of Java then you’ll be able to turn your exceptions into sealed classes as well.

Now, if you tell me that you don’t want to handle exceptions, that’s fine with me. In my case, whenever I can I will use it, either in (BBDD, Files …). It is highly unlikely that I will get such an error and if it occurs I will know (not from the code) if not from the custom error message.

You do you of course. But do you not see how null safety sidesteps this entire design pattern? You don’t need a host of exceptions to handle nulls where they shouldn’t be, because they can’t. If you want better error messages you can return an Either type (or use Kotlin’s built-in Result) instead. Most functional languages already figured this out to the point that the concept of exceptions doesn’t even exist.

I guess this is like everything. Use what you like best. I prefer to use good practices.

You are not using good practices. You are applying design patterns from one language on another language, without understanding why this pattern exist and if it applies to this new language. You are solving a problem that either does not exist, or can be solved better by the language’s features.

Seeing the “NS with?” Reminded me that all Kotliners good practices are going to disappear.

Not just Kotlin programmers; also Python programmers, C# programmers, Bash and Powershell scripters, Swift programmers, Rust programmers, Haskell programmers and more.

And that’s a good thing, the compiler/language helping the programmer can never be a bad thing. I want to spend my time writing code that is worthwhile, not writing defensive null checks and try-catches.

Surely you as someone with C programming experience must know what a relief it is to program in Java without worrying about (de)allocating memory, and the amount of freedom you get when you don’t have to design your code in a way that facilitates the pain of manual memory management.

Many popular languages now also offer that ease for null. In these languages, null isn’t that annoying edge case you have to check for even though your documentation clearly tells the user not to pass null there, or that return value you have to check for because the author couldn’t be bothered to detail whether or not a method returns null or not.

The consensus in the programming world has become that (outside of removing the concept of null completely) null safety is the way forward. Older languages are adding null-safe operators and newer languages come with them included. You’re free to disagree with the programming industry, but you should ask yourself what it is the world sees that you don’t. Even Java introduced Optional as way to add null-safety.

Doing a simple search to San Google we have:

Java (these are lazy to put Generics, predicates and more things):
link
Java:
link
This is my style, but a lot is missing
link
Official documentation never fails. (Although things are missing)
link
What do the python guys think?
Link
What will those of REST services think?
link
Good practices for long projects
link
Those of .NET
link
8 searches counted in 1 minute.

I could spend all day and tomorrow and the day after … We may not read the same pages in Europe … I do not read the New York Times.

Now I understand many things and especially strange and unstructured projects without a framework that I find myself sometimes. One of two, or I have made a mistake when reading good practices and standards or you have not received the information.

On something that we agree on.

Do you know how to make a compiler or when you try to program an Arduino board doing wifi / TV in assembly code (ARM)? Try to omit the nulls by applying NS. When you do, give me a call and tell me how it went. 0x00.
In case you think I am lying, it is not that I am lying, they have knocked on my door and given me the good practice book.
https://developer.arm.com/documentation/102412/0100/Handling-exceptions
https://developer.arm.com/documentation/dui0471/m/handling-processor-exceptions/exception-handling-process

It’s hard when someone from the other continent makes you see reality. We will always have to learn. Knowing “occupies” place, it is a fact.

On patterns, this already comes from 2004 and before. In case someone never did, it’s good to learn.

https://www.sciencedirect.com/topics/computer-science/code-error-handling

Every day someone goes to sleep with something new learned.

You completely missed my point, you argued that Sometimes we had nulls and we didn’t know what type it was.. Not knowing what type something is cannot happen in Java or Kotlin.

One of two, or I have made a mistake when reading good practices and standards or you have not received the information.

The former I’m afraid.

Do you know how to make a compiler or when you try to program an Arduino board doing wifi / TV in assembly code (ARM)? Try to omit the nulls by applying NS. When you do, give me a call and tell me how it went. 0x00.

Assembly code has no null-safety, so I’m not sure what your point is. If you want a systems language that does not suffer from null-related bugs among many other things I can wholeheartedly recommend Rust.

All in all I have no clue what exception handling has to do with null-safety, or null-safe operators.

1 Like