I have my Java program and I get a NullPointerException and I have seen other questions but they are from people with other programs and it does not work for my program and I want to leave you here the 2,000 lines of my program so that you can solve the problem for me but people do not let.
Look, my program is like this
Object a = null;
// 500 líneas de código
// Dentro de un bucle, dentro de un if, dentro de un for...
a = algunaFuncionDeMilLineasQueNoTeVoyAMostrar(
parámetrosDeLosQueNoTeDiréElValor)
// Cerrando for, cerrando if, cerrando bucle.
// Otras 500 líneas de código
// Una de estas líneas lanza el NPE, pero no te diré cuál.
a.toString();
z.hazAlgunaCosa();
x.haxY().hazM().cuantoFaltaParaLasVacaciones().andaMiraUnPatoQuePasaPorAhi();
It's wrong? Why isn't there a one-size-fits-all solution for NullPointerExceptions (NPEs) if they happen so often?
The solution is (drum roll)...
Do not use methods or properties of a null variable or expression
If you have a line:
and throws you an NPE, it is that when you execute
p
it it is worthnull
. Make sure it has a non-null value before executing the line.That is all...
There is no need to repeat the same question a million times, even if the program is different.It's clear, isn't it? As promised, resolved forever and ever.
If your line is something like
it is exactly the same, if any of the methods returns null , when trying to call its corresponding method the JVM will throw the NullPointerException. The only difference with the previous example is that the JVM will only show you an error on the line and you will have to find out in which step the null appears .
This has changed a bit since version 14 of the language, which introduced an option to tell the JVM to give us more detailed messages about the code that throws exception 1 . This option is disabled by default, so to enable it it is necessary to include the JVM command line parameter
-XX:+ShowCodeDetailsInExceptionMessages
when executing the program.And now is when someone protests: "But that doesn't help me with my problem that I get a NullPointerException in my program that I write here 2 "?
The answer: If there is a NullPointerException, your problem is not the NullPointerException.
It is the responsibility of a programmer to know how their program works and how the data is organized. It's not the kind of question that can be downloaded to StackOverflow. If you have an NPE, you are in one (or more) of these cases:
The typical case is to say "in this method it
a
can be 1 or 2" and doYour problem is that it is
a
worth something you did not expect, coupled with the fact that you do not program defensively and do not control the values. Debug your program to fix the value ofa
, add onedefault
that throws an exception when the value is unexpected.You have such a complicated method that you don't know when values are assigned to the reference. Modify your program so that it is easy to read and understand. Don't do like the old Elbonians who said "Writing is easy, we hope to learn to read one day". If you want to check if your program works as you expect, use a debugging tool or generate log messages so that you can verify its operation. If you need someone from the Internet to explain how your program works, consider another profession.
You have a problem with the API. You have followed all the steps mentioned above, and in the end you have found that the cause of the origin is that you are calling
java.util.Collections.toArray()
and it returns a valuenull
. Check the documentation of the method, check the parameters you pass, etc. If you still can't find the solution, Congratulations!!!! Now you have a question that is valid for SO ("Why does java.util.Collections.toArray() return null to me?")You have a vector that you initialized in some way, but you never initialized it internally. Doing this
tipo1 vector[] = new tipo1[n];
does not imply that the vector will be magically filled with objects of type1 . You must do a New type1 for each position of the vector.One more note about arrays
As it is a confusion that appears quite frequently, we will insist on the last point:
When creating an array of objects, the array is created but the objects are not created . After the first line of code above, you have the object myArray (you can do myArray.length ), but that object only contains 10 references ( myArray[0] , myArray[1] ...) to null ; the instances they point to have yet to be assigned. If those references are not assigned an instance, then attempting to invoke methods or attributes will throw a NullPointerException.
1 For more information see JEP 358: Helpful NullPointerExceptions .
2 Followed by a thousand lines of code, and of course without even indicating on which line the NPE is launched.
If you suspect that the variable has a
null
y will give an error,NullPointerException
solve it by adding a try-catch block and it will recover the error. You can give your objects anew Object
and it will upload thenull
as a string to your application so you can see which object breaks the flow of your program.You can also read the warnings in the code, they help a lot.
How about good afternoon, of course there is a solution to handling the NPE and it is not necessarily the handling of the exception, I recommend that you use the Null Object Pattern design pattern , this will make your code more robust and you will have control of it type of errors, thus preventing the program from being interrupted at runtime.
Here is the UML diagram:
The implementation is really simple. I recommend that you do not validate object.something.something != null and do not abuse generalized try/catch either because that will not solve your problem, they will only be controlling it but the underlying problem will continue to exist.
Cheers!!!
Part of your problem is probably that you
funciondeMilLineas
are doing very long and very convoluted functions in which it is easy to make mistakes. A simple rule of thumb for how long a function should be is that it can be viewed on a screen. That's around 40 lines on my monitor. You can play with the size of the letter, but more or less that is the length.It is not easy to learn to break code into functions. What I have read on the subject that I liked the most was in a book by Robert C. Martin called Clean Code and it has an entire chapter on functions. There what he says is:
Obviously it is a bit difficult to understand what this means and apply it in practice. But I think it's worth learning that before making programs that work but then are too convoluted to extend.
The thing about
NullPointerException
is that you haven't initialized any Java references. Simplifying it to the beast is that you are missing somethingnew
somewhere.PS: If you really get to a function of a thousand lines, do not doubt that it is wrong. That has to be divided.
If I could contribute something, which I don't think so, because they have responded quite well above (now I will give the vote) I would add:
-if it is a parameter, you should check it before using it. -if it's a result, use optionals
Example:
You can implement a
try{}catch(NullPointerException){}
since, as it says, it catches all the fields that are null or make sure that they are not null when calling them. you can implement a method that receives the object and check that it is not nullor better make sure when programming that it already contains the reference or that it is initialized.
There is one option that doesn't seem to be used much to mitigate the NullPointerExceptions issue, and that is the
java.util.Objects
. This class, present in the JDK since Java 7, contains several static methods that can help a lot in handling nulls.The most basic is simply testing whether a variable is null or not. It is usually done:
It always bothered me a bit to have to use == because it's not usually the right way to compare objects (although it works as expected in this case). With the objects class we can do:
If we also import Objects statically:
It is much clearer, concise and elegant. Also, it's even better when used in Streams, such as in a filter:
Another method that I find cool from the Objects class is requireNonNullElse() (although this method is only present since Java 9). Normally we would do something like this if we want to assign a variable verifying that it is not null:
(we could also use the ternary operator here, but it would be similar). With Objects, we could do:
There is another similar version that accepts a supplier as the second argument:
What is the difference between the two? the way Java works, requireNonNullElse() will evaluate the second argument even though the first argument isn't null and doesn't need to return it. So if this second argument is something that is difficult to create, takes up a lot of memory or a lot of processing, you can use requireNonNullElseGet() and build the object in the body of the supplier. Since the result of the lambda expression is not going to be evaluated until it is actually needed, we save ourselves from creating something that is not going to be used.
There are a few other methods in the Objects class that help prevent NullPointerExceptions, but these seem to me to be the most important. You can check the documentation here: https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/Objects.html
It is easily solved, validating. NullPointerExceptions are said to be generated by programmer errors, if you know that a method can return an object or needs to work on an object, just put a: