I've got this method I'm working on (I think that's the name) and it essentially tries to match a part of a string and then return the proceeding part of the string - that part I've got, easy stuff. The method is of type String.
When my method fails to find the pattern in the string I want it to return an empty string. I also want to send something along with the empty string to go "hey, I didn't find your key" but I want this to be optional.
This is essentially what I want the method to do:
public static String getKey(String key) throws KeyNotFoundException {
if (key.equals("something")) {
return "great";
} else {
throw new KeyNotFoundException();
return "";
}
}
But the problem with this code is that the return ""; is obviously unreachable due to throw new KeyNotFoundException();.
If I was going to call this method I'd have to use the try {} catch(KeyNotFoundException knf) {} block. It's this block that I want to make optional however.
If I choose to be oblivious to the fact the key was not found (e.g. don't use try catch) then I just want to be given the empty string on return.
But I also want to be able to surround it with a try-catch block if I need to know whether the key was found for my operation to complete correctly.
I think I'm going about this the wrong way but I can't seem to figure out an alternative (new to Java), could anyone shred some light on this please?
The usual way to do this would be to write two methods, one which returns a default value, and one which throws an exception. You can have one of these call the other, to avoid duplication:
public static String getKey(String key) throws KeyNotFoundException {
String value = getOptionalKey(key);
if (value.equals("")) throw new KeyNotFoundException(key);
return value;
}
public static String getOptionalKey(String key) {
if (key.equals("something")) {
return "great";
} else {
return "";
}
}
The caller can then choose which one to call, based on their needs:
String value = getOptionalKey("uma"); // oblivious
try {
String value = getKey("uma"); // cognisant
}
catch (KeyNotFoundException e) {
// panic
}
You should either use return values or exceptions to denote an error condition, but not both.
Generally, if you anticipate that something can go wrong, use a return value, and if the error is exceptional, throw an exception (as the name suggests).
By definition, an exception disrupts the normal program flow. The exception "bubbles up" until someone catches it or the thread terminates.
You can't do exactly what you're trying, but you have a couple options. You could write a "safe" version of the method that returns a default value if the key isn't found, like you're trying to do, and have a separate method that will throw the exception if the key isn't found.
Another option, if you've defined KeyNotFoundException yourself, would be to derive from RuntimeException instead of simply Exception. Then, you could remove the throws declaration from your method signature and not publish the fact that the method could throw an exception.
You can't, however, throw an exception from the method AND return a value from the method.
Another way you could deal with optional return values is to use Java 8's Optional class, and let the caller decide what to do when the value is not present:
public static Optional<String> getOptionalKey(String key) {
if (key.equals("something")) {
return Optional.of("great");
} else {
return Optional.empty();
}
}
You could combine it with the multiple methods approach discussed in other answers:
public static String getKey(String key) throws KeyNotFoundException {
return getOptionalKey(key).orElseThrow(() -> new KeyNotFoundException(key));
}
What about if you create your own Exception (extend Exception) which will have a constructor that takes a String or whatever you want to send to it (like error code or statement)?
Then you can have a getter method within your Custom Exception that will be used to "get" whatever the error message was.
nope. a method can only end with returning a value/end or return; if it is void OR throw an exception.
From what I understand of what you want to achieve, you could use a void returning method and provide a reference of a special object in argument. you would then set a field of this object to the result you want to 'return' and throw the exception.
Something like
class final ResultHoder {
String result;
public void setResult(String result) {
this.result = result;
}
public String getResult() {
return this.result;
}
}
public static void getKey(String key, ResultHolder result) throws KeyNotFoundException {
if (key.equals("something")) {
result.setResult("great");
return;
} else {
result.setResult("");
throw new KeyNotFoundException();
}
}
Related
I have a method that handles different error codes and always throws unchecked exception. This method is used in many places across the class. When I try to call it inside another method that has not void return type as shown below:
public Object someMethod() {
....
if(success){
return result;
} else {
callMethodThatAlwaysThrowsUncheckedExceptions();
}
}
java compiler says that the method is missing return statement.
Only two options come to my mind how to solve this problem:
replace method call with its content
add a return statement just after method call that returns an empty object
However I don't really like any of these options: the first one because of code duplication and the second one because of the need to write code that will never be executed.
Is there any other way to solve this problem?
Just swap around the terms, you'll never get to return if the method throws.
if(!success){
callMethodThatAlwaysThrowsUncheckedExceptions();
}
return result;
Or even
callMethodThatAlwaysThrowsUncheckedExceptions(succes);
return result;
Just check the success condition in your throwing method.
Next to the great answer already provided by Slawomir Chodnicki, here's another suggestion.
Change your callMethodThatAlwaysThrowsUncheckedExceptions() which somewhere throws an Exception into a factory method. E.g: change this:
// somewhere in callMethodThatAlwaysThrowsUncheckedExceptions
throw new MyException();
To:
return new MyException();
That way you can call that method like this:
throw callMethodThatAlwaysThrowsUncheckedExceptions();
And thus will help the compiler to see that this is the last statement of that execution branch.
This also works greatly with different exceptions, just return instead of throw
To indicate that you don't expect a line to be reachable (after your call to the throwing method) you can
throw new AssertionError("comment to your co-developers why this never gets reached")
I like minus's answer, but it can be a bit unreadable to users that might mistakenly think return result; will always be executed (regardless of the value of success).
As an alternative, you can change
void callMethodThatAlwaysThrowsUncheckedExceptions () {}
to
Object callMethodThatAlwaysThrowsUncheckedExceptions () {}
(no need to change the method body).
Now you can write
public Object someMethod() {
....
if (success) {
return result;
} else {
return callMethodThatAlwaysThrowsUncheckedExceptions();
}
}
None of the answers above matched my taste of programming. The closest match that I found is here. Inspired from this linked answer, I handled such missing return statement errors in the following way:
First making the return type of the method same as that of exception which it always throws
MyCustomRuntimeException callMethodThatAlwaysThrowsUncheckedExceptions() {
// ....
throw new MyCustomRuntimeException();
}
Next whenever we have to fail the method execution, simply call above method and throw it
public Object someMethod() {
// ....
if (success) {
return result;
} else {
throw callMethodThatAlwaysThrowsUncheckedExceptions();
}
}
This can be used even in methods having void return type without explicitly mentioning the throw keyword. Ofcourse in such places some IDEs may warn of UnusedReturnValue but that can be suppressed as well.
Is there any solution i can break a running method which is supposed to return an int[] or whatever but !without! any return value.
I thought that might work with some exception but i didn't find a propper way. To be more specific i want something which tries to find out if a certain field of an object was set and if yes return it and if no returns a message which tells me that the input wasn't made so far.
something like this:
public int[] returnArray(){
if(array_was_set==true) return the array;
else show message that it wasnt set and quit the method without any return value;
}
One way of doing that, return null and make the caller decide , if the caller gets a nun-null (or maybe a non-empty) array it will process it in some way and if the caller get an empty or null array it could print a message.
I would recommend against using exceptions as a substitute for return values see this question to know more about when to throw an exception.
There are three options to choose from, depending on your scenario:
Use return value of null (and document it)
Throw an exception with a detailed message. I would use this version only for exceptional cases such as illegal API usage or a logical error situation(bug).
Return a wrapper class, containing both a return value and some other message, when relevant
Edit: Another 2 options:
Use polymorphism - Return type can be Result, and concrete subclasses can be NoResult and DataResult.
Instead of returning null, return a constant value defined as:
static final NO_RESULT = new int[0];
Later you can check the returned value against it (using == condition).
You should be able to do it by raising an exception. Just use the message in the exception's constructor.
However, exceptions are relatively expensive and if this isn't really an error condition you should consider doing something else, such as returning null to indicate there is nothing to return.
Yes better way is use Exception
example
public static void main(String[] args) {
try {
new Result().returnArray(false) ;
} catch (Exception e) {
}
}
.
public int[] returnArray(boolean input) throws Exception {
if(input) {
return new int[]{1};
}
else {
System.out.println("Not match");
throw new Exception();
}
}
When you declare in the method signature that it is returning a data type then it must have a return statement which returns that specific type value. Otherwise you will get compile-time error.
The only exception when a method can avoid return statement even though it has return type is when there is an infinite loop or an exception is thrown. Otherwise return statement is compulsory.
Coming to your question, you can easily achieve what you are doing. If you want to terminate at a particular point as per your requirement just say,
return null;
It will work for all the data types except for primitive types in which case you need to do type casting to Wrapper class types appropriately.
public int[] returnArr() {
if(some condition)
return SomeIntArray;
else
return null;
}
public int returnInt() {
if(some condition)
return 2;
else
return (Integer)null;
}
In code we have got a lot of chain methods, for example obj.getA().getB().getC().getD(). I want to create helper class which will check if method getD() isn't null, but before that I need to check all previous getters. I can do it in this way:
try {
obj.getA().getB().getC().getD();
}
catch (NullPointerException e) {
// some getter is null
}
or (which is "silly")
if (obj!null && obj.getA()!=null && obj.getA().getB()!=null && ...) {
obj.getA().getB().getC().getD();
}
else {
// some getter is null
}
I don't want to check it every time using try{} catch() in my code. What is the best solution for this purpose?
I think that the best will be:
obj.getA().getB().getC().getD().isNull() - for this purpose I will need to change all of my getters, for example implement some interface which contains isNull() method.
NullObjectHelper.isNull(obj.getA().getB().getC().getD()); - this will be the best (I think so) but how to implement this?
As of Java 8 you can use methods like Optional.isPresent and Optional.orElse to handle null in getter chains:
boolean dNotNull = Optional.ofNullable(obj)
.map(Obj::getA)
.map(A::getB)
.map(B::getC)
.map(C::getD)
.isPresent();
While this is preferable to catching NullPointerException the downside of this approach is the object allocations for Optional instances.
It is possible to write your own static methods that perform similar operations without this overhead:
boolean dNotNull = Nulls.isNotNull(obj, Obj::getA, A::getB, B::getC, C::getD);
For a sample implementation, see the Nullifier type here.
No approach is likely to have greater runtime efficiency than nested if-not-null checks.
You can achieve the desired result with Option pattern. This enforces you to change a method signature, but basically if your method returns some type T, it guarantees it has some non-null value, and if it returnsOption<T> it means it either has value T, or null.
Java 7 had some feature called null safety, but it was removed from the final release. You could do:
obj?.getA()?.getB()?.getC()?.getD()
Moreover, Java 8 will add a feature called Optional so you would do it safely.
In fact, if you really want to use that now, try Null Object pattern. It means that instead of returning plain null you can return some sort of default value, which won't trigger NullPointerException. Though, you need add some changes to your getters
class Object {
A getA() {
// ...
return a == null ? A.NULL : a;
}
}
class A {
static A NULL = new A(); // some default behaviour
B getB() {
if (this == NULL) return B.NULL;
// ...
return b == null ? B.NULL : b;
}
}
EDIT: If you want utility to do it you can wrap it in some functional interface and then call it.
static boolean isNullResult(Callable call) throws Exception {
try {
return call.call() == null;
} catch (NullPointerException npe) {
return true;
}
}
Usage will be the following:
isNullResult(new Callable<Integer>() {
#Override
public Integer call() throws Exception {
return new A().getB().getC().getInt();
}
});
It won't require you to change existing functionality
As already stated, the true solution is refactoring.
In the meantime, you could just wrap your first workaround in a function:
static D getD(MyClass obj) {
try {
return obj.getA().getB().getC().getD();
}
catch (NullPointerException e) {
return null; // Or even better, some default D
}
}
At the caller site:
D d = getD(obj);
At least you don't have to trash the caller with try-catch blocks. You still need to handle the errors somehow, when some of the intermediate getX() call returns a null and so d becomes null. The best would be to return some default D in the wrapper function.
I don't see how the two options you list at the end of your question would help if any of the intermediate getX() returns a null; you will get a NullPointerException.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
Is it "bad practice" to effectively cache the result of executing expensive stateless checking code by returning a null in the case of a "no problem found"? The upside is minimal code and no class/code bloat.
This is illustrated by this code:
public static String getErrorMessage(SomeState x) {
// do some "expensive" processing with "x"
if (someProblem)
return "Some problem";
if (someOtherProblem)
return "Some other problem";
return null; // no error message means "all OK"
}
And the calling code:
String message = getErrorMessage(something);
if (message != null) {
display(message);
return;
}
// proceed
This pattern avoids having to repeat executing the expensive code twice by returning null to mean "there's no error message, because there's no error". And there's no extra "low value" classes/code.
The obvious alternatives are A) to separate out the concerns of checking and message creation:
public static boolean isOK(SomeState x) {
// do some "expensive" processing with "x"
return thereIsNoProblem;
}
public static String getErrorMessage(SomeState x) {
// do some "expensive" processing with "x"
if (someProblem)
return "Some problem";
if (someOtherProblem)
return "Some other problem";
}
And the calling code:
if (!isOK(something)) {
display(getErrorMessage(something)); // expensive code called a second time here
return;
}
// proceed
which executes the expensive code once to determine if there's a problem, and again to determine what the problem is, or B) to return a "result" object that has a boolean field to answer the "if" part and a String field to answer the "message" part, eg
class MyResult { // like a struct in C
boolean ok;
String message;
// accessor methods omitted
}
public static MyResult verify(SomeState x) { ...}
And the calling code:
MyResult result = verify(something);
if (!result.ok) { // spare me the lecture on accessors - this is illustrative only
display(result.message);
return;
}
which creates class bloat and is a little clumsy IMHO.
Is it "bad" to "overload" the return value in this way?
It is certainly "neater" than all the alternatives I can think of.
If you offer an alternative, say why you think returning null is "bad". State the risks or downside to justify not using this simple technique.
There are a limited number of options for reporting an error/abnormal condition within a called function:
Return a value (if the function can/does return a value) that indicates "error".
Return an error code at a location indicated by a "error pointer" parameter to the function.
Throw an exception.
Pass control to a previously-defined (or parameter-designated) "delegate" or "callback".
Update a global error indicator.
Invoke a global error routine.
None of these is especially attractive -- global is bad, we know, a delegate/callback is clumsy and verbose, and exceptions are slow (and the mark of the beast, as we all know). So the first two are the options most often used.
With 2 there is the problem that if you do return an error from a value-returning function, you still need to return a value. And, for an object-returning function, nil is the most logical value to return.
You kind of end up returning nil regardless.
I would use:
public class ValidationResult {
public final boolean isValid;
public final String errorMessage; // may be null if isValid == true
public ValidationResult(boolean isValid, String errorMessage) {
if (!isValid && errorMessage == null) {
throw new IllegalArgumentException();
}
this.isValid = isValid;
this.errorMessage = errorMessage;
}
}
Then:
public static ValidationResult validate(SomeState x) {
// blah
return new ValidationResult(isValidTest, errorMessageIfNot);
}
And:
ValidationResult r = validate();
if (!r.isValid) {
display(r.errorMessage);
}
Alternatively, you could have it throw a checked exception.
public class ValidationException extends Exception {
// your code here
}
Then:
public static boolean validate(SomeState x) throws ValidationException {
// ...
if (isValid) {
return true;
} else {
throw new ValidationException(message):
}
}
Your initial solution is perfectly fine, null is perfect to represent the "absence of" a return value.
I've decided to work on my comment to make it an answer. I think this is a good context for an enumeration, something like this:
public enum OperationStatus {
ERROR1 {
#Override
public String toString() {
return "err1";
}
},
ERROR2
//The same as error 1
//
//Many error types here
SUCCESS {
#Override
public String toString() {
return "ok";
}
}
}
This way, your method can return a value of this enumeration specifying the actual error with a code that you can get as a String. This is in particular if you plan to localize such errors by having, for example, localized bundles that you can switch and obtain the associated value to each of the defined codes.
On the other hand, this would work if you don't plan to add errors in the future or if you can afford the occasional modifications this enumeration would require if new error types arise.
An alternative (you'd still need to update this array, but you prevent yourself from having an enumeration) to avoid the enum, a simple Stirng[] would do the trick too, since you can return an int as an error code and use it as an index of that array to obtain the actual code you can interpret, display and localize.
Instead of checking isOK() then getting the error message, just add a throws exception to isOK() with appropriate message, then use a try/catch to display the error message.
There doesn't seem to be a reason to have multiple layers of checking then getting the errors when one function would suffice with throws.
It's ok as long as you are using it by yourself but it could be improved somehow. About why it could be improved, let me quote Tony Hoare:
I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years.
First of all you could use exceptions:
public static String getErrorMessage(SomeState x) throws YourException {
// do some "expensive" processing with "x"
if (someProblem)
throw YourException("Some problem");
if (someOtherProblem)
throw YourException("Some other problem");
return null; // no error message means "all OK"
}
Then you can have a custom object:
class ErrorState {
boolean hasFoundError;
String message;
ErrorState() {
hasFoundError = false;
}
ErrorState(String message) {
hasFoundError = true;
this.message = message;
}
public final static ErrorState NO_ERROR = new ErrorState();
}
Finally if the set of potential errors is finite you could just use an enum (which is in my opinion the better choice):
enum ErrorState {
NO_ERROR(""),
SOME_ERROR("Some error"),
SOME_OTHER_ERROR("Some other error");
public final String message;
ErrorState(String message) { this.message = message; }
}
I'm pretty anti-NULL, and, personally, would return the empty String "" to mean no error, or perhaps a constant like "OK". But null is acceptable.
The enum / value object concept does feel a bit like overkill, but often the requirements expand and you'll eventually need something like that.
In cases where there can be multiple errors, I like to return a List of Strings, and an empty list obviously means no problemo. In this case, do not return null, return an empty list.
Below is the class somebody else wrote.
The problem that I am facing is that when it get's into the parse method with null as the rawString, it is throwing NumberFormatException.
So what I was thinking to do is, I should catch that NumberFormatException and set the value itself as null. So the way I did is right?
public class ByteAttr {
#JExType(sequence = 1)
private Byte value;
public static ByteAttr parse(String rawString) {
ByteAttr attr = new ByteAttr();
try {
attr.setValue(Byte.valueOf(rawString));
} catch (NumberFormatException nfEx) {
attr.setValue(null);
}
return attr;
}
public Byte getValue() {
return this.value;
}
public void setValue(Byte value) {
this.value = value;
}
}
The correct approach depends on what you want to accomplish in the program.
If it makes sense for ByteAttr.getValue() to return null later in your program, then your approach could work.
However, you need to consider whether you should be throwing an exception if parse is called with an indecipherable argument (including null). An alternative is to catch the NumberFormatException and throw a different exception that has semantic meaning in your program.
public static ByteAttr parse(String rawString) throws BadAttributeException {
ByteAttr attr = new ByteAttr();
try {
attr.setValue(Byte.valueOf(rawString));
} catch (NumberFormatException nfEx) {
throw new BadAttributeException(nfEx); // wrap original exception
}
return attr;
}
Another technique is to pass a default value to parse for those cases when rawString is indecipherable:
public static ByteAttr parse(String rawString, Byte defaultValue) {
ByteAttr attr = new ByteAttr();
try {
attr.setValue(Byte.valueOf(rawString));
} catch (NumberFormatException nfEx) {
attr.setValue(default);
}
return attr;
}
You need to do four things:
Decide what an unparsable number string means in the context in which you will be using the method. Does it mean an internal problem in the program? A corrupt file? A user typo? Nothing wrong but that string needs to be handled differently?
Decide the best way to handle it, taking that into account. Almost always, if the error is triggered by external input you need to report it back. Substituting null may be a good way of handling it.
Document what you decide to do. If a method is going to return null with some specific meaning, that needs to be written down as comments, preferably Javadoc commments.
Implement your decision.
I get the impression, perhaps unfairly, that you have jumped straight to step 4, without thinking through the possible causes and proper reporting of the problem.
You can add an early exit with a condition like:
if (rawString != null) {
return attr; // or other value you prefer
}
You can also make sure the caller of the parse method test for null value and avoid calling parse when it is.
It depends on the tolerance to null values in your application. If you expect the users to not pass null string to the parse() method, then you should do a defensive null check and throw an exception.
if (null == rawString) {
throw new CustomException("rawString cannot be null");
}
The same would apply to the catch block for NumberFormatException, where instead of silently setting the value of Byte attribute to null, you should throw an exception with appropriate message.
But if null is perfectly acceptable, then you should perform a defensive null check and set the Byte attribute to null. The NumberFormatException should certainly be NOT suppressed, IMHO.