I have this problem where I initialize a variable outside of a forloop. And then inside of the forloop try to update the value of this variable but everytime I "local variable not used". I tried a simple example (below) and the problem is still there. Ret is highlighted in my compiler and the error message is displayed. I don't understand why I can't access variables inside my loops anymore. Is this possibly due to me missing a bracket somewhere in my methods somewhere else in the class?
public static String test(String input) {
String ret = "";
for(int i=0;i<5; i++) {
ret += "m";
}
return "";
}
I was wondering if someone could help me with this. I would really appreciate it. Thanks!
You get this error message because you are building the ret variable but you are not using it. For example if you use the variable in an if statement you will not get the error anymore.
public static String test(String input) {
String ret = "";
for(int i=0;i<5; i++) {
ret += "m";
}
if (ret.equals("mmmmm")){
ret +="";
}
return "";
}
I suspect your IDE or compiler is noticing that you build up text in the local var ret but you never use that text. That built-up text is discarded, and you return an empty string. Your tools are alerting you to this nonsense.
Also, you make no use of the argument passed to your static method, more nonsense.
Related
I have the following method that normalises a given XML tag name:
public static String normaliseTagName(String tagName) {
// Return a given empty tag name.
if (tagName.length() == 0) {
return tagName;
}
// Replace invalid start.
if (isInvalidXMLStart(tagName.charAt(0))) {
tagName = XML_REPLACEMENT + tagName;
}
// Replace invalid characters.
StringBuilder normalised;
boolean invalidFound = false;
for (int i = 0; i < tagName.length(); i++) {
if (isInvalidXMLChar(tagName.charAt(i))) {
if (!invalidFound) {
normalised = new StringBuilder(tagName.substring(0, i));
invalidFound = true;
}
normalised.append(XML_REPLACEMENT); // COMPILER ERROR
} else if (invalidFound) {
normalised.append(tagName.charAt(i)); // COMPILER ERROR
}
}
return invalidFound ? normalised.toString() : tagName; // COMPILER ERROR
}
I don't want to initialise the StringBuilder normalised before I'm sure to use it. In other words, I want to only initialise it when an invalid XML character is found.
I get The local variable normalised may not have been initialized errors where indicated, and I'm puzzled as to why the compiler is telling me that when normalised is clearly never used uninitialised.
Am I missing something or is the compiler unable to determine the initialisation path of the StringBuilder normalised in this situation?
If this compilation error cannot be avoided, how can I modify this code so that I initialise the StringBuilder only when I need it?
Thanks!
You need to explicitly initialize your local variable:
StringBuilder normalised = null;
... or ...
StringBuilder normalised = new StringBuilder();
... before referencing it.
Some of the pathways in your code reference normalised prior to its initialization:
normalised.append(...
Local variables are not automatically initialized as would, instance fields.
I have troubles returning a value from a loop in method.
I've tried this way: (which returns classname, my initialise String instead of classes.get(i).className)
public String getClassName(){
String cName = "classname";
for (int i=0; i<classes.size(); i++){
cName = classes.get(i).className;
}
return cName;
}
and I've tried this as well: (which returns c instead of classes.get(i).className)
public String getClassName(){
String cName = "classname";
String c = "c";
for (int i=0; i<classes.size(); i++){
c = classes.get(i).className;
}
cName = c;
return cName;
}
Please tell me how to return classes.get(i).className!! Thanks a lot :P
There is nothing stored in classes. Make sure you have in there what you think you do. Try putting this inside the for loop to see what's going on:
System.out.print("class name = " + cName);
If this never prints out, you know that classes is empty. At any time inside the for loop, you can call return, for example if the class name matches something you can test for in an if statement.
for (int i=0; i<classes.size(); i++){
cName = classes.get(i).className;
return cName;
}
Also, could you upvote, or mark someone as correct? (I'm new and would love to have some good answers marked as such :) )
I don't know what are you trying to do, but your code is equivalent to:
public String getClassName() {
return classes.get(classes.size() - 1).className;
}
Are you sure this is what you want to return? You should be careful in case classes is empty as you might get ArrayIndexOutOfBoundsException.
While Maroun is right bout the code only returning the last value in the classes collection, the reality is that in your example the collection is always empty, and thus the for loop does not execute even once. Make sure the classes collection contain what you think it should!
That should be because you dont enter the for loop mainly because you list "classes" is empty.
You can check it this way-
if(classes.size()==0)
System.out.println("Classes is empty");
Method:
public String getRowsOf3Stars (int rows)
Description:
Compulsory Exercise 2) Complete the getRowsOf3Stars method which is
passed an int(rows) as a parameter. The method returns a String
containing that number of 3-stars rows.
For example,
getRowsOf3Stars(2) // returns ā***\n***\nā
If rows is less than 1, returns an empty String.
An example:
getRowsOf3Stars(2) // should return "***\n***\n"
What I wrote:
public String getRowsOf3Stars (int rows) {
String getRowsOf3Stars="***\n";
if (rows<1){
String none="";
return none;
}
else{
for(int starRows=1;starRows<rows;starRows++){
return getRowsOf3Stars;
}
}
}
The error I recieve on CodeWrite:
private String getRowsOf3Stars(int rows) throws Exception {
>> This method must return a result of type String
Can someone please explain why my program isn't returning a String?
change this
for(int starRows=1;starRows<rows;starRows++){
return getRowsOf3Stars(starRows); // your code here don't return any thing here.
Put return ""; as last line of your method to get rid of the error. It's complaining because there is a chance your current lines where you're returning might never be called due to the conditions you have.
If for example you provide an argument rows = 1, the return will never happen.
Java compiler would make sure that there is a string return from the method.
Now see the code,
1) if(rows<1)
then only if will work and return a string.
2)But if (rows>=1)
then it will go to the for loop, and the compiler cannot determine at the compile time that the for loop will execute or not, as this is a runtime mechanism.So its not sure for the compiler that for loop will execute or not.
And if for loop doesn't execute, your method will not return anything.
Now since compiler has to make it sure, that there should be a string return, it is showing that error.
So what you can do is that, in the else clause after for loop you can return a default string as return ""; or as per your requirement.
In addition to the issue of not returning a string, I don't see a reason for the internal loop as you are issuing a return inside the loop. I think this would accomplish what you want:
public String getRowsOf3Stars (int rows) {
String ROWOF3STARS = "***\n";
String returnString = "";
if (rows > 0){
for(int starRows=1;starRows<rows;starRows++){
returnString += ROWOF3STARS;
}
}
return returnString;
}
Hope this helps.
In the expression of a while loop, is it possible to initialise a variable, then use that as part of the expression?
It's probably simpler in code:
while (int a = someMethod(), a<b)
It would be possible to just add another method, and so have to following:
private boolean whileLoopTest() {
int a = someMethod();
return a<b;
}
public void originalMethod() {
while (whileLoopTest()) {
//...
but this doesn't seem as neat.
EDIT
I also don't want to directly compare the method to my variable, as it is compared to several variable, and so if would be a long, unreadable mess. A better example of what I want would be:
while (int a = SomeClass.someStaticMethod(), -1<a && a<b)
It's not true in my case, but this would be a equally valid question if someStaticMethod() took a long time to return - I would only want to call it once.
I'm fairly new to StackOverflow, so I'm not sure if giving other situations where this would apply is what I should be doing.
int a;
while((a = someMethod()) < b){
//do something
}
A common use for this is reading from a file:
BufferedReader fileIn = ...
String line;
while((line = fileIn.readLine()) != null){
//do something
}
fileIn.close();
/edit
You can do this for your new scenario:
int a;
while(-1 < (a = SomeClass.staticMethod()) && a < b) {
//do something
}
Once the left hand portion of the && statement is executed, the return value of SomeClass.staticMethod() is stored in a, which carries over the the right hand portion of the statement.
Why not just not assign the value to "a" if you are not using it anyways?
while (someMethod() < b) { doSomething() }
If you actually do need "a" then your alternate solution would not work. The solution then would be either to save it (which I do not consider unneat) or what Kerrek said.
You can use the function directly without using a local variable like this:
while ( someMethod() < b) { /* ... */}
This, if your method returns intended value. (If you are casting it to a local variable, it's supposed to)
EDIT: For your second question.
Your concern is understandable, but if you are assigning that methods value to a local variable inside while loop's boolean expression, in every loop where "While" checks the expression, you are assigning methods' return value to local variable, which means you are calling that method in every iteration. That doesn't change anything from my first answer.
I have a recursive method that reversed a string (HW assignment, has to be recursive). I did it....but its only returning the value of the string after the first pass. By analyzing the output after each pass i can see it does do its job correctly. heres my code, and the output i get below it:
String s = "Hello, I love you wont you tell me your name?";
int k=0;
public String reverseThisString(String s) {
if(k!=s.length()) {
String first =s.substring(0,k)+s.charAt(s.length()-1);
String end = ""+s.substring(k, s.length()-1);
k++;
s=first+end;
System.out.println(s);
this.reverseThisString(s);
}
return s;
}
output:
?Hello, I love you wont you tell me your name
I think you need to change this:
this.reverseThisString(s);
to this:
return this.reverseThisString(s);
otherwise the result of the method call is simply discarded.
I would also recommed that you change k to be a parameter to the method rather than a member.
Like Mark said, you forgot the return statement.
Also, there is an easier way to reverse a string (which is my current homework too :P )
public String reverse(String s) {
if(s.length() <= 1)
return s;
return reverse(s.substring(1))+s.charAt(0);
}