Reputation: 4686
I'm kinda waiting for a 'no' answer on this question.
I was interested if you can save a variable at the same time when you checking it in an if-clause.
Let's say I have this code.
if(foo!=null){
if(foo.getBar()!=null){
Bar bar = foo.getBar();
System.out.println("Success: " + bar);
} else {
System.out.println("Failure.");
}
} else {
System.out.println("Failure.");
}
I handling now to "failure" -states independently, even if the outcome is the same. I could get them together like this:
if(foo!=null && foo.getBar()!=null){
Bar bar = foo.getBar();
System.out.println("Success: " + bar);
} else {
System.out.println("Failure.");
}
Much neater code already. if foo is null it will stop there and won't try foo.getBar (in the if) so I won't get a NPE. The last thing i would like to enhance, and the main question: Do I really gave to call on foo.getBar() twice? It would be nice to get away from the second identical call if getBar() would be a very heavy operation. So I am wondering if there is somehow possible to do something similiar to this:
if(foo!=null && (Bar bar = foo.getBar())!=null){
Bar bar = foo.getBar();
System.out.println("Success: " + bar);
} else {
System.out.println("Failure.");
}
I would have to break it up to two different if's again if I would like to do
Bar bar = foo.getBar();
if (bar!=null) ...
Upvotes: 24
Views: 11665
Reputation: 11
Duc Minh Vu said it, but I have found out this line of code inside the OncePerRequestFilter#doFilter
in Spring Boot:
if (!((request instanceof HttpServletRequest httpRequest) && (response instanceof HttpServletResponse httpResponse))) {
throw new ServletException("OncePerRequestFilter only supports HTTP requests");
}
Spring boot version: 3.4.1
I found next in a documentation (in a nutshell):
Starting from Java 16 the Pattern Matching for instanceof was introduced to avoid next lines of code
if (obj instanceof String) {
String s = (String) obj; // grr...
...
}
Upvotes: 0
Reputation: 61536
if you want to limit the scope of Bar bar I'd add { and } around the code that Michael posted.
void foo()
{
// some code ...
// this block limits the scope of "Bar bar" so that the rest of the method cannot see
// it.
{
Bar bar;
if(foo!=null && (bar = foo.getBar())!=null){
System.out.println("Success: " + bar);
} else {
System.out.println("Failiure.");
}
}
}
You might also want to check into the null object pattern if it makes sense. I personally try to avoid things being null if I can... really think about if you want null to be allowed or not.
Upvotes: 7
Reputation: 15
With pattern matching in Java 14, you can get even closer:
if(foo != null && foo.getBar() instanceof Bar bar) {
// instanceof itself does null-check
System.out.println("Success: " + bar);
} else {
System.out.println("Failure.");
}
Upvotes: 0
Reputation: 11829
You cannot declare a variable in a Java conditional, but you can in a for
loop:
for (Bar bar = (null != foo) ? foo.getBar() : null; bar != null;) {
System.out.println("Success: " + bar);
break;
}
But it is not pretty. I completely agree with Tom Hawtin's comments.
Upvotes: 0
Reputation: 1
Actually I think that is a way to do this using Java Optional, here's an example:
Optional.ofNullable("text").ifPresent( $0 -> {
System.out.println($0.toUpperCase());
});
Or in your case:
if(foo != null){
Optional.ofNullable(foo.getBar()).ifPresent(bar -> {
System.out.println("Success: " + bar);
});
}
Upvotes: 0
Reputation: 147164
Three points that completely fail to answer the question:
null
is evil. Don't write methods that return it. Your example problem would then disappear.
I think you might be missing out on encapsulation. Instead of foo.getBar()
could the interface of foo
be made such that you perform a "tell don't ask" operation?
Side-effects in expression tends to cause bad code. Prefer more, simpler lines to fewer, buggy lines. The usual exception if using ++
to increment an index when accessing a buffer, or similar iterator style algorithms.
Upvotes: 2
Reputation: 328724
From the department "My Programming Language is Better Than Your Programming Language": In Groovy, you can use the "?." operator:
Bar bar = foo?.bar
if (bar != null) {
}
In Java, this is good pattern(*):
Bar bar = foo == null ? null : foo.getBar();
if (bar != null) {
}
*: Something you can save in your fingertips.
Upvotes: 2
Reputation: 27998
I have used that technique when iterating over lines from a BufferedReader:
BufferedReader br = // create reader
String line
while ((line = br.readLine()) != null) {
// process the line
}
So yes, you can do an assignment, and the result off that will be the left hand side variable, which you can then check. However, it's not legal to declare variables inside a test, as they would then only be scoped to that expression.
Upvotes: 14
Reputation: 346377
This is the closest you can get:
Bar bar;
if(foo!=null && (bar = foo.getBar())!=null){
System.out.println("Success: " + bar);
} else {
System.out.println("Failiure.");
}
Upvotes: 39