There are many similar topics, but I can't find exactly where my problem is..
CustomerDetails - abstract class
The method reads from a file, where first letter determines the types of a customer (which are sub-classes of CustomerDetails).
public static CustomerDetails readCustomerData(....)
try
{
while(...hasNextLine())
{
.....
.....
switch(firstLetter)
{
case 'A': ....
PrivateCustomerDetails aaa = new PrivateCustomerDetails(... inherited fields + some extra ones)
return aaa;
case 'B': ... BusinessCustomerDetails bbb = .....
return bbb;
default: return null;
}
}
// possibly return something here..
}
catch(Exception e)
{
...
return null;
}
I have noticed that if I enter "return null;" at a comment field above, missing return statement disappear. But I cant get why? I have possible scenarios as well as default statement, which covers all other cases.
Moreover, I can't initialize CustomerDetails object, assign new objects of sub-classes to it and return, since it is abstract..
Also, I can't make the names of the objects of sub-classes the same to return it in the end..
Need some clarification.. Thanks very much!
What if hasNextLine() returns false the very first time you call it? What would be returned in that case? You need a return statement to handle that possibility.
If you don't expect that to happen, an alternative is to throw an exception.
Because it is possible that the while loop is never executed. In this case you have to return a value.
Related
I have a if condition like the below
if (!null= xya)
return xya
{
a=b;
return abc
}
or which is it better to avoid return statement before entering in to loop
I'm very confused about the question, but this is how I imagine that code should look:
if (xya != null){
return xya;
}
else{
a=b;
return abc;
}
I have absolutely no idea what this code is meant to do, or why you need to declare a = b then return abc but if you're wondering why your code doesn't work that's probably it. As the other answer suggests, it's possible to completely remove the else case, but I feel like you need to keep your code as rigidly structured as possible for the time being.
Interpreting your question as, "Is there a better way to write a return statement, i.e. without using an if block?" If this isn't what you requested, please rewrite your question, as it is very difficult to understand what you're asking.
From your code, I'm thinking that you're trying to do a null-check, and return xyz if it's not null. Otherwise, do some other code, and return abc. Let's fix your code first.
if (xyz != null) {
return xyz; // Remember that after every statement, you need to have a semicolon.
} else {
a = b;
return abc;
}
You don't need to write an else statement within an if block. Knowing this, since your code would end if it xyz was not null, we don't need to write our code in the else statement, because the code after the if block is independent of the if block. Let's revise your code, then.
Try this:
if (xyz != null)
return xyz; // Since it's only one line, brackets are optional.
a = b;
return abc;
If you're coming from a different language (i.e. Lua), I'd highly recommend reading some syntax tutorials on Java. It'll save you a lot of frustration later. I recommend the following Java Tutorials, and just explore and read from the beginning. It's a great way to get the basics of syntax, especially with if statements.
Edit:
I've been told that bracketless conditionals may hinder code readability. Here are some alternatives to writing without them:
if (xyz != null) {
return xyz;
}
a = b;
return abc;
You could alternatively have the if statement in one line, as shown:
if (xyz != null) { return xyz; }
a = b;
return abc;
I have a method that returns all the names of people in a LinkedList for a plane.
However even though there is a return statement in the method, I'm still getting told there is a missing return statement.
How can I work around this without putting another return statement in? Why isn't it considered valid? Does putting another return statement in change what is returned?
Any feedback is greatly appreciated.
public String check() {
for (Person person: passengers)
{
return person.getName();
}
}
Because if passengers is empty, the loop will never be entered.
If the loop is never entered, assuming the only return statement is in it, we have a serious problem, don't you think ? It's like if there were no return at all.
You need to add another return statement outside of the loop.
Also note that the return will automatically exit the method, so I don't think this is exactly what you wanted as per this sentence in your question :
I have a method that returns all the names of people in a LinkedList
for a plane.
Edit
As per your edit, here how you can return a list containing all names :
return passengers.
.stream()
.map(Person::getName)
.collect(Collectors.toList());
Note that you will need to change the signature of your method to
public List<String> check()
In answer to your question in the comments. You can only return a single object from a function. You could take another container and populate it with the names and return that. For example,
public LinkedList<String> check() {
LinkedList<String> names = new LinkedList<String>();
for (Person person: passengers) {
names.add( person.getName() );
}
return names;
}
What exactly are you trying to accomplish, here?
Currently, check will only ever return the name of the first passenger. Think about how your program flows and what you want it to do.
To answer your question, you need to have an 'escape' for every possible path in your code. Even if a certain block should always catch and return (not by definition, but just by how you think the code should flow), you need to handle the case such that that block doesn't catch and return. This can be done by either fixing the first block so that it really is a catch-all, or by simply returning or throwing an error if the first block doesn't catch.
i.e.
public boolean check() {
...
if (shouldAlwaysBeTrue) return false;
}
doesn't work because shouldAlwaysBeTrue is not true by definition.
public boolean check() {
...
if (shouldAlwaysBeTrue) return false;
return true;
}
I want to verify multiple conditions for validations. Currently, I have it set up such that in case of an error, each condition returns the error message, and an empty string in the absence of any errors. As a result, my code looks something like this:
String error = condition1(argA, argB);
if (!"".equals(error)) {
return error;
}
error = condition2(argC, argD);
.
.
.
and so on.
I wanted to know if there's a more elegant way of doing this in Java (or cofeescript)?
How about rather than having a lot of if statements you just create one method to check since if seems the check is the same for all conditions like.
public String check(String err)
{
if (!"".equals(err))
{
return err;
}
return err;
}
Now whenever you checking you just call the method
check(condition1(argA,argB));
and
check(condition2(argC,argB));
The string returned ofcause you know what to do with it.
Hope that helps
I'm refactoring a very large method with a lot of repetition in it.
In the method there are many while loops which include:
if ( count > maxResults){
// Send error response
sendResponse(XMLHelper.buildErrorXMLString("Too many results found, Please refine your search"), out, session);
break;
I want to extract this as a method, because it happens 3 times in this one method currently, but when I do so I get an error on the break as it is no longer within a loop. The problem is that it is still necessary to break out of the while loops, but only when the maximum number of results are reached.
Any suggestions?
Suppose the method is :
public boolean test(int count, int maXResult) {
if ( count > maxResults) {
// Send error response
sendResponse(XMLHelper.buildErrorXMLString("Too many results found, Please refine your search"), out, session);
return true;
}
return false;
}
Call method from loop as :
while(testCondition) {
if (test(count, maxResults)) {
break;
}
}
This is impossible to do directly.
Most often you want to break because you have found the solution and no longer have to search. So indicate in the called function that there is/was success, for instance by returning a result or a boolean to indicate success. And if the function returns success, then break.
If it is now within a method instead of the while loop have it return a value and then break based on that.
i.e.
public bool refactoredMethod(parameters)
{
if ( count > maxResults){
// Send error response
sendResponse(XMLHelper.buildErrorXMLString("Too many results found, Please refine your search"), out, session);
return true;
}
return false;
}
Try to break the loop in the method using return;
As Thriler says you cant do it directly. You could extract part of it to the method and do something like:
if(isTooManyResults(count)) { break; }
Obviously your isTooManyResults method would need to return true if there are too many results and false otherwise
I just noticed one curious case and wanted to see if someone will be able to explain it. Here is my case:
private enum Classifiers {
NEURAL_NETWORK, NEAREST_NEIGHBOURS, IDENTITY;
}
private ClassifierInterface getClassifierInstance(Classifiers classifier) {
switch (classifier) {
case NEURAL_NETWORK:
return new DoubleLayeredNeuralNetwork();
case NEAREST_NEIGHBOURS:
return new NearestNeighbours();
case IDENTITY:
return new IdentityClassifier();
}
return null; // If I comment out this line I get compilation error
}
See the comment. I would expect that Unreachable code error will be reported for this line. Instead I get Method must return value error if I comment out this line. However, there is no way the program flow will pass through there.
I even assumed it would be a guard case for the case of null value passed-in, but as expected this triggers NullPointerException for the switch condition.
I do not use switch very often, probably I am missing something here. Can somebody please try to help understand this behaviour?
That is correct behaviour as you do not have a default case statement. The problem is that you could add an value to the enum later and not re-compile the code which uses it. By forcing you to always handle when it is not one of the values, this is covered.
BTW: classifier could be null which is another option switch doesn't handle unfortunately.
That question is interesting...
We have something like this and the compiler is happy!
public enum Coin {
PENNY,
NICKEL,
DIME,
QUARTER;
}
private enum CoinColor { COPPER, NICKEL, SILVER }
private static CoinColor color(Coin c) {
switch(c) {
case PENNY:
return CoinColor.COPPER;
case NICKEL:
return CoinColor.NICKEL;
case DIME: case QUARTER:
return CoinColor.SILVER;
default:
throw new AssertionError("Unknown coin: " + c);
}
}
The Java Languaje Specification says:
A Java compiler is encouraged (but not required) to provide a warning
if a switch on an enum-valued expression lacks a default label and
lacks case labels for one or more of the enum type's constants. (Such
a statement will silently do nothing if the expression evaluates to
one of the missing constants.)