i wrote an function like
public static boolean check()throws Exception
{
if(a=="asd")
return true;
else
return false;
}
this works fine
but if i use
public static boolean check()
{
try
{
if(a=="asd")
return true;
else
return false;
}
catch(Exception e)
{
}
}
it says you need to return an value,,,, is there is any difference between these two???
you need to return something in the catch, a method always need to return something, even in catch, unless you throw/rethow an exception.
Yes, there is a difference. Your second code block will catch any exception from the if statement and swallow it, and then resume running after the catch block. But there is no return statement there, so if there is any exception, the function will have no return value.
The first code block, on the other hand, uses throws to indicate that Exception descendants may escape from it instead of being caught, so it doesn't need to catch and handle anything itself, and the compiler is prepared to allow the function to not return anything (due to exiting early from an exception).
Java has methods, not functions. So you didn't write a function, but a method. Also, comparing strings with == does not work in Java. You have to call the equals() method instead:
if (a.equals("asd"))
The problem in your second piece of code is this: What happens if an exception occurs? The content of the catch block is executed, and after that the rest of the method is executed. Note that there is no code after the catch block. But the method requires that you return a boolean - you're missing a return statement. Change it like this:
public static boolean check()
{
try
{
if (a.equals("asd"))
return true;
else
return false;
}
catch(Exception e)
{
}
// You need to add a return statement here
return false;
}
There are some more comments that can be made about your code.
First of all, it's always a bad idea to leave a catch block empty. Because when an exception is caught, nothing will happen, and you'll never know that something went wrong. Always handle exceptions appropriately.
Also, code like this:
if (a.equals("asd"))
return true;
else
return false;
can be simplified like this:
return a.equals("asd");
The result of the expression a.equals("asd") is already a boolean; why would you check again if it's true or false and then return true or false?
Not all paths in the code will return a value. Since you have a catch there, if an exception is thrown, no value will be returned because the code in the catch will execute.
I think you should return the value at the end of function after catch. Try to store result in one boolean variable and return that variable after catch. This may solve your problem
A premise:
a=="asd" is not 'wrong' but probably it is better to use a.equals("asd") because == compares pointers, not equality. For example ("asd"=="asd") == false but ("asd".equals("asd")) == false
If if(a=="asd") throws an exception, the flow goes in the catch, and then it exits without ever finding the return statement. the correct code could have a return statement inside the catch block
Jesper's answer pretty much covers it. I needed to show some code so therefore this separate answer.
You will have to decide in each situation how to handle exceptions. Jesper and LordSAK both chose to return 'false'. A problem with this is that you can't distinguish the error condition from the case that 'a' is not equal to "asd".
A possible solution is to change the method's return type to Boolean (the Object version of the primitive boolean) and return 'null' in case of an exception
public static Boolean check() {
try {
return "asd".equals(a);
}
catch(Exception e) {
return null;
}
}
Another option is to re-throw your exception as an unchecked exception:
public static boolean check() {
try {
return "asd".equals(a);
}
catch(Exception e) {
throw new RuntimeException("Problem during check", e);
}
}
A drawback of this approach is that the code calling your check() method does not expect a runtime exception to be thrown. Because this type of exception is unchecked the developer will not get a compiler warning if he doesn't surround the call to check() with try-catch.
A third option is to just declare the exception and let your calling code handle it. A full example:
import org.apache.log4j.Logger;
public class Checker {
private static final Logger LOG = Logger.getLogger(Checker.class);
private String a;
public Checker(String value) {
a = value;
}
public boolean check() throws Exception {
return "asd".equals(a);
}
public static void main(String[] args) {
Checker app = new Checker("Stackoverflow");
try {
app.check();
}
catch(Exception e) {
LOG.error("Problem during check", e);
}
}
}
An advantage is that you don't have to decide which value check() returns in case of an error, but instead you just return the error itself. This is actually the whole idea of 'throwing' exceptions.
As a rule of thumb: if you can't handle an exception within the method itself, then throw it and let the calling code deal with it.
An example from the wild: A method handling an exception itself.
private static final long DEFAULT_TIMEOUT = 60000;
public long getTimeout(String timeoutArg) {
try {
return Long.parseLong(timeoutArg);
}
catch(NumberFormatException e) {
return DEFAULT_TIMEOUT;
}
}
NB: I didn't compile or run any of this code, so there might be typos.
Related
This question already has answers here:
Java Compiler Error: Missing Return Statement
(2 answers)
Closed 4 years ago.
I'm using the code below in a Triangle class to allow the user to set the first, second, or third point of a declared Triangle.
public Point get(String p) throws IllegalArgumentException {
IllegalArgumentException e = new IllegalArgumentException();
try {
if (p == "first") { return first; }
else if (p == "second") { return second; }
else if (p == "third") { return third; }
else { throw e; }
}
catch (e) {
System.out.println("Error: " + e);
}
}
The compiler is telling me:
Triangle.java:41: error: missing return statement
}
^
But I thought the point of the catch statement was to be able to catch an error and return a string describing the error, without having to worry about matching the function's return type.
Because you're missing a return statement.
The method declares that it returns something, so it must return something (or throw an exception). The compiler can't guarantee that any of the return statements in the try block will be reached if an exception is thrown before any of them execute. So the catch block also needs to return something (or throw an exception, or return something after the try/catch construct entirely).
Edit: Looking again, you're also potentially missing a return in the try block. (If you don't have one after the entire try/catch structure.) What if none of the conditions in the if/else structure are satisfied? Nothing is returned. Which is invalid.
Basically, all logical paths must result in a valid exit of the method. You've missed two such paths.
You're not returning anything in your function on several paths.
But I thought the point of the catch statement was to be able to catch an error and return a string describing the error, without having to worry about matching the function's return type.
That's not at all what a try-catch does, and moreover your function is declared to return a Point not a String.
try-catch simply "catches" a Throwable (Error or Exception) and allows you to run some code when it is thrown instead of simply terminating the application with an Uncaught Exception/Error.
You need to return some value from your function after the try-catch there is no way to return a string, nor is there a language construct in place that behaves like you've explained your understanding of try-catch.
Also your code cna't actually throw an IllegalArgumentException so your catch block will never get called. In this case, it sounds like what you want is instead something like this
public Point get(String p) throws IllegalArgumentException {
if (p == null) { throw new IllegalArgumentException(); }
if (p.equals("first")) { return first; }
else if (p.equals("second")) { return second; }
else if (p.equals("third")) { return third; }
else { throw new IllegalArgumentException(); }
}
The code could then be called like so
Point p;
try {
p = get("notFirst");
} catch (IllegalArgumentException ex) {
//oh no, we gave a bad argument, and the method told us nicely.
}
You are missing two parts:
1. A return statement in try block for else condition
2. Catch block doesn't lead to a return statement or a throw statement
I don't know if type of first, second, third variables are string or Point, but you should return with Point, because your function is :
public Point get(String p) {
...
}
You have three if statements. What happens when the input doesn't satisfy any of those? Your method doesn't have a return statement for that case.
I know how to assert that an Exception is thrown. But, how can I assert that an Exception was thrown and it was successfully caught? For example, say I have a method which should throw a particular type of exception for invalid inputs
public static void myMethod(String value) {
try {
someExternalMethod(value);// can throw IllegalArgumentException
} catch (IllegalArgumentException e) {
System.out.println("Let me handle it differently");
} catch (Exception e) {
System.out.println("Not IllegalArgumentException");
}
}
Now I want to assert that for some values the method indeed has thrown 'IllegalArgumentException' and not some other Exception.
In the context of testing myMethod you cannot (and more importantly, you should not want to) check that someExternalMethod has thrown IllegalArgumentException. In fact, your tests of myMethod should not assume that a call of someExternalMethod has been made: it is an implementation detail of myMethod.
The very reason myMethod catches these exceptions is to hide them from its callers. You should check that these exceptions are hidden from you by passing values that cause them, and verifying that nothing is thrown in both cases.
Testing someExternalMethod, along with the exceptions that it throws, is the task accomplished by testing someExternalMethod, not myMethod.
You're missing the important point of unit testing - tests should test behaviour, not implementation.
Given this assumption you should be testing the behaviour of myMethod is as expected when an IllegalArgumentException occurs. It's hard to say any more than that with the method you've shown given the parameter, a single String is immutable, there is no return value and no exceptions are thrown.
A better example might be this method (which is a little contrived to demonstrate the point):
public double divide(int numerator, int denominator)
{
try
{
return numerator / denominator;
}
catch (ArithmeticException e)
{
return Double.NaN;
}
}
Where your tests would assert that the division is correct and that when an error occurs NaN is returned, like this:
#Test
public void testDivide()
{
assertEquals(2.0, divide(4, 2), 0);
}
#Test
public void testDivideByZero()
{
assertTrue(Double.isNaN(divide(1, 0));
}
You could then re-write the divide method like this:
public double divide(int numerator, int denominator)
{
if (denominator == 0)
{
return Double.NaN;
}
else
{
return numerator / denominator;
}
}
And the tests would confirm the operation of my system because the behaviour of the divide method remains unchanged.
catch blocks are evaluated in the order they are.
Your code works fine: in case of IllegalArgumentException, Exception block will be ignored.
Mock method someExternalMethod(value) to force throw Exception
Test method myMethod, checking that is not throwing Exception:
#Test
public void testMyMethod() {
try {
myMethod("value");
} catch (Exception ex) {
Assert.fail();
}
}
So I'm trying to catch exceptions where I can't return a Directory, but Java won't let me. How do I structure the code so that Java will let me run it?
public Directory pathToDir(String path) throws Exception {
String[] arrayPath = path.split("/");
Directory cwd_copy = FileSystem.getRoot();
try {
// full path
if (path.startsWith("/")) {
for (int x = 1; x < arrayPath.length; x++) {
if (stuff) {
} else {
throw new Exception();
}
}
}
return cwd_copy;
}
catch (Exception e) {
pathErrorMsg();
}
}
No, you may be throwing an exception, but then you catch it and do nothing with it! If you step through that code logically, you'll see that there are possible pathways for the method to end without a Directory being returned and for no exceptions to be thrown. That won't fly.
Consider instead,....
public Directory pathToDir(String path) throws PathToDirException {
String[] arrayPath = path.split("/");
Directory cwd_copy = FileSystem.getRoot();
// full path
if (path.startsWith("/")) {
for (int x = 1; x < arrayPath.length; x++) {
if (stuff) {
} else {
throw new PathToDirException( /* some text goes in here! */ );
}
}
}
return cwd_copy;
}
Where PathToDirException is a checked exception class you've created for problems with this method/class.
Or if you have a try/catch block in the method, and need to then throw an exception, throw your new Exception class, but pass the caught exception into your new exception as a constructor parameter.
If I understand your question, you need a return at the end of your method (in case you catch an Exception instead of returning cwd_copy)
return cwd_copy; // <-- this didn't happen.
} catch (Exception e) {
pathErrorMsg();
// return null; // <-- you could return here.
}
return null; // <-- so you need something. null or cwd_copy
Or add a return in the catch block.
Because an exception could be caught1, a value must still be returned from the catch path.
try {
maybeThrowException();
return X;
}
catch (Exception e) {
// But what is returned here?
}
Either don't catch the exception, [re]throw an exception, or return a value in the case when the catch block is entered.
Since the method is declared to throw an Exception, it probably should throw one on failure - the method contract should specify the result in such a case.
1 Java actually isn't that smart, even if it is a logical way to think about it. The try/catch is treated like an if/else here and all branches must logically lead to a return (or throw). It would still be a compiler error even if the try was empty and could never throw an exception. Consider the following comparison:
if (true) {
return X;
} else {
// But what is returned here?
// (Java does not consider that this can never be reached,
// just as it does not logically consider the content of a `try`.)
}
I have a question regarding return statements used within if() while() or for() statements.
As you can see in the following method, it is expecting that I return a String value. The problem is that if I were to use a return statement within my if statement block, the compiler would return the error missing return statement.
public String myMethod()
{
if(condition)
{
return x;
}
}
Of course I could change the method header to void and use System.out.println instead of return. But is this the right way to do it? Am I missing something?
If you put a return statement in the if, while or for statement then it may or may not return a value. If it will not go inside these statements then also that method should return some value (that could be null). To ensure that, compiler will force you to write this return statement which is after if, while or for.
But if you write an if / else block and each one of them is having a return in it then the compiler knows that either the if or else will get executed and the method will return a value. So this time the compiler will not force you.
if(condition)
{
return;
}
else
{
return;
}
That's because the function needs to return a value. Imagine what happens if you execute myMethod() and it doesn't go into if(condition) what would your function return? The compiler needs to know what to return in every possible execution of your function.
Checking Java documentation:
Definition: If a method declaration has a return type then there must
be a return statement at the end of the method. If the return
statement is not there the missing return statement error is thrown.
This error is also thrown if the method does not have a return type
and has not been declared using void (i.e., it was mistakenly
omitted).
You can do this to solve your problem:
public String myMethod()
{
String result = null;
if(condition)
{
result = x;
}
return result;
}
That is illegal syntax. It is not an optional thing for you to return a variable. You must return a variable of the type you specify in your method.
public String myMethod()
{
if(condition)
{
return x;
}
}
You are effectively saying: I promise any class can use this method (public) and I promise it will always return a String (String).
Then you are saying IF my condition is true I will return x. Well, that is too bad. There isn't any IF in your promise. You promised that myMethod will always return a String.
Even if your condition is always true, the compiler has to assume that there is a possibility of it being false. Therefore you always need to put a return at the end of your non-void method outside of any conditions just in case all of your conditions fail.
public String myMethod()
{
if(condition)
{
return x;
}
return ""; // Or whatever the default behavior will be if all of your conditions fail to return.
}
Try with, as if the if condition returns false, so it will return empty, otherwise nothing to return.
public String myMethod()
{
if(condition)
{
return x;
}
return ""
}
Because the compiler doesn't know if any of those if blocks will ever be reached, so it's giving you an error.
You have to add a return statement if the condition is false.
public String myMethod() {
if(condition) {
return x;
}
// if condition is false you HAVE TO return a string
// you could return a string, a empty string or null
return otherCondition;
}
FYI:
Oracle docs for return statement
This will return the string only if the condition is true.
public String myMethod()
{
if(condition)
{
return x;
}
else
return "";
}
Anyhow, myMethod() should return a String value. What if your condition is false? - is myMethod returning anything? The answer is no, so you need to define return null or some string value for the false condition:
public String myMethod() {
boolean c = true;
if (conditions) {
return "d";
}
return null; // Or some other string value
}
I want to run method x if method y fails. For example
public void createzoo (){
create.chimp();
if
activateByMail.chimp() fails
run
activateByAdmin.chimp()
delete.chimp();
}
It would be good if I could use boolean to accomplish this.
I'm writing scripts in java on ubuntu
return boolean value from chimp() function it something goes wrong in it. and check like
if(!activateByMail.chimp())
activateByAdmin.chimp();
you can do it in these both ways,
1.
make the return type of method1 as boolean, which if fails return false, true otherwise.
boolean method1(){
if(succeed)
return true;
else
return false;
}
//use it like this:
if(!method1()) method2();
2
. if you already have a return value in that method, throw some exception in method 1, and catch it in the call. and in catch block call method2.
void method1(){
if(!succeeed) throw new FailException();
}
use it like this
try{
method1();
} catch(FailException ex){
method2();
}