Java Setter Using User Input - nullpointerexception

To make sure this doesn't get closed, read this. This isn't a duplicate post because the only other user input setter is in C or c something and if not that it's for a completly different application. How can I set up my setWord method to use user input and not be null. My current code gives off a null pointer because the variable is null, but I can't find out a viable way to set it's value using user input. Current code: Subclass:
package hangman;
public class Hangman {
private String word;
public void setWord(String word) {
this.word = toString();
}
public String getWord() {
return this.word;
}
#Override
public String toString() {
System.out.println("Enter secret word: ");
return (this.getWord());
}
}
Main
public static void main(String[] args) {
Hangman hangman = new Hangman();
hangman.setWord();
String secretWord = hangman.getWord();
StringBuilder b = new StringBuilder(secretWord.length());
}
Again, the issue is that I can't find a way to set the private String "word" to user input without it ending up being null. Please dont mark this as duplicate I already looked at the generic cookie cutter nullpointerexception threads but haven't helped me at all. I've been stuck on this and it's my last part of my program. The null pointer is always at the stringbuilder, which suggests that secretWord is null.

Think about it: where do you ever set the word? setWord assigns the return of toString, which returns the result of getWord, but getWord just returns what this.word already was! Nowhere do you ever set a word, so it's never initialized! You just set this.word to what it was originally, which was null. This causes an NPE when you call secretWord.length(), since secretWord is null.
You have another problem, which I'm assuming is a typo here, where your call to setWord in your main isn't given an argument. That's illegal and creates an error of its own, so it should never reach the StringBuilder line.
Change setWord to:
public void setWord(String word) {
this.word = word; ; Set it to its argument
}
Then call it with a word as the argument:
hangman.setWord("Word");

Originally I had a toString which served no functional purpose. And the setWord method required a parameter which I didn't have so to fix it I replaced the setWord code with this
public void setWord() {
Scanner scan = new Scanner(System.in);
System.out.println("Enter the secret word: (Under 7 letters)");
this.word = scan.nextLine();
this.word = word;
}

Related

how to get the fully qualified name of a method call when it exists in the source code using javaparser

My test code to excercise various functions of JavaParser:
public class test001 {
public static void main(String[] args) {
test001 t = new test001();
t.run();
}
#sample.mkGetSet
int g1;
#sample.start
test001(){
g1 = 14;
}
#sample.funky
void run() {
#sample.flagVar
int a,b,c;
a=1;
b=2;
c=a+b;
c=c+g1;
System.out.println("result:"+c);
}
}
My code correctly notes that I call println in the method run.
Is there a fairly easy way to get the 'System.out.' part in addition to the println part?
In the case where the qualification is not there, I dont need it but if it is i would like it.
The type of answer I'm looking for is along the line of 'In the MethodCallExpr look at XXXXX' (with the obligatory admonition to RTFD)
I've been over the documentation and its still not clear how to do this - or if i even can.

how to catch minor errors?

I have a little ANTLR v4 grammer and I am implementing a visitor on it.
Lets say it is a simple calculator and every input must be terminated with a ";"
e.g. x=4+5;
If I do not put the ; at the end, then it is working too but I get a output the teminal.
line 1:56 missing ';' at '<EOF>'
Seems it can find the rule and more or less ignores the missing terminal ";".
I would prefer a strict error or an exception instead of this soft information.
The output is generated by the line
ParseTree tree = parser.input ()
Is there a way I can intensify the error-handling and check for that kind of error?
Yes, you can. Like you, I wanted a 100% perfect parse from user-submitted text and so created a strict error handler that prevents recovery from even simple errors.
The first step is in removing the default error listeners and adding your own STRICT error handler:
AntlrInputStream inputStream = new AntlrInputStream(stream);
BailLexer lexer = new BailLexer(inputStream); // TALK ABOUT THIS AT BOTTOM
CommonTokenStream tokenStream = new CommonTokenStream(lexer);
LISBASICParser parser = new LISBASICParser(tokenStream);
parser.RemoveErrorListeners(); // UNHOOK ERROR HANDLER
parser.ErrorHandler = new StrictErrorStrategy(); // REPLACE WITH YOUR OWN
LISBASICParser.CalculationContext context = parser.calculation();
CalculationVisitor visitor = new CalculationVisitor();
visitor.VisitCalculation(context);
Here's my StrictErrorStrategy class. It inherits from the DefaultErrorStrategy class and overrides the two 'recovery' methods that are letting small errors like your semicolon error be recoverable:
public class StrictErrorStrategy : DefaultErrorStrategy
{
public override void Recover(Parser recognizer, RecognitionException e)
{
IToken token = recognizer.CurrentToken;
string message = string.Format("parse error at line {0}, position {1} right before {2} ", token.Line, token.Column, GetTokenErrorDisplay(token));
throw new Exception(message, e);
}
public override IToken RecoverInline(Parser recognizer)
{
IToken token = recognizer.CurrentToken;
string message = string.Format("parse error at line {0}, position {1} right before {2} ", token.Line, token.Column, GetTokenErrorDisplay(token));
throw new Exception(message, new InputMismatchException(recognizer));
}
public override void Sync(Parser recognizer) { }
}
Overriding these two methods allows you to stop (in this case with an exception that is caught elsewhere) on ANY parser error. And making the Sync method empty prevents the normal 're-sync after error' behavior from happening.
The final step is in catching all LEXER errors. You do this by creating a new class that inherits from your main lexer class; it overrides the Recover() method like so:
public class BailLexer : LISBASICLexer
{
public BailLexer(ICharStream input) : base(input) { }
public override void Recover(LexerNoViableAltException e)
{
string message = string.Format("lex error after token {0} at position {1}", _lasttoken.Text, e.StartIndex);
BasicEnvironment.SyntaxError = message;
BasicEnvironment.ErrorStartIndex = e.StartIndex;
throw new ParseCanceledException(BasicEnvironment.SyntaxError);
}
}
(Edit: In this code, BasicEnvironment is a high-level context object I used in the application to hold settings, errors, results, etc. So if you decide to use this, either do as another reader commented below, or substitute your own context/container.)
With this in place, even small errors during the lexing step will be caught as well. With these two overridden classes in place, the user of my app must supply absolutely perfect syntax to get a successful execution. There you go!
Because my ANTLR is in Java I add the answer here too. But it is the same idea as the accepted answer.
TempParser parser = new TempParser (tokens);
parser.removeErrorListeners ();
parser.addErrorListener (new BaseErrorListener ()
{
#Override
public void syntaxError (final Recognizer <?,?> recognizer, Object sym, int line, int pos, String msg, RecognitionException e)
{
throw new AssertionError ("ANTLR - syntax-error - line: " + line + ", position: " + pos + ", message: " + msg);
}
});

How do you use code fragment mode in the Intellij debugger?

In the debugger, you can press alt-f8 and evaluate an expression.
There's also a code fragment mode. The documentation in IntelliJ only says:
Code Fragment Mode for evaluating short code portions introducing them
in the Statements to evaluate text field. Supported constructs are
declarations, assignments, loops and if/else.
I can't find any examples on the web of how to use it and can't figure out myself.
Can you give examples of how to use the supported constructs?
Given
public class CodeFragment {
public static void main(String[] args) {
List<Foo> list = new ArrayList<Foo>();
list.add(new Foo("555"));
list.add(new Foo("777"));
list.add(new Foo("999"));
list.add(new Foo("bill"));
System.out.println();
}
public static class Foo {
String s;
public Foo(String s) {
this.s = s;
}
}
}
If we set a break point on the println, we can put the following into the code fragment
Foo resultFoo = null;
Iterator<Foo> it = list.iterator();
while (it.hasNext()) {
Foo foo = it.next();
if (foo.s.equals("777")) {
resultFoo = foo;
}
}
resultFoo = resultFoo;
This demonstrates declaration, assignment, a loop, and an if.
Note that the foreach loop is not supported, in older versions of intellij!
Also note the assignment at the end. As far as I can tell, the result that gets displayed is the result of the last statement. Without that last statement, this code would display 'false' - ie the result of the last call to it.next.

ArrayList method is creating an error upon calling

Hello everyone I'm tying to create a method that receives a list of string values and returns the list in reverse. The for loop is supposed to traverse the values in reverse order, starting with the last element. I'm getting an error message when I try to call the method in the main method, I don't know what argument to pass. Here is my code.
enter code here :import java.util.*;
public class ThisList
{
public static void main (String[] args)
{
list(ArrayList<String> words);
}
public static ArrayList<String> list(ArrayList<String> words)
{
ArrayList<String> phrase =new ArrayList<String>();
words.add("before");
words.add("gone");
words.add("has");
words.add("man");
words.add("no");
words.add("where");
words.add("go");
words.add("bodly");
words.add("To");
for(int i= words.size()-1; i>= 0; i--)
{
phrase.add(words.get(i));
}
return phrase;
}
}
Your problem lies in how you are calling your list() function in main, specifically in how you are improperly sending in your argument. You should not declare/initialize an object in the calling of a function. It is syntactically incorrect, plus how would you access it afterwards? Even if it was possible to declare an object in the calling of the function, the words array is also uninitialized when you are trying to use it. Also, your function list() is returning an ArrayList. You are not setting an ArrayList in your main() function to be set to the returning ArrayList(phrase) from list().
I would advise looking over Object-Oriented programming basics and a few beginner Java tutorials so you can get a better understanding to be able to solve this kind of problem on your own.
http://docs.oracle.com/javase/tutorial/java/concepts/
Below is the code you posted, with the proper way to call your function. If this is what you need, do not forget to upvote and select this answer as the correct one! (Upvote by pressing the up arrow next to the post, and accept answer by clicking the checkmark next to the post so that it turns green).
import java.util.*;
public class ThisList
{
public static void main (String[] args)
{
ArrayList<String> words = new ArrayList<String>();
ArrayList<String> phrase_returned = list(words);
}
public static ArrayList<String> list(ArrayList<String> words)
{
ArrayList<String> phrase =new ArrayList<String>();
words.add("before");
words.add("gone");
words.add("has");
words.add("man");
words.add("no");
words.add("where");
words.add("go");
words.add("bodly");
words.add("To");
for(int i= words.size()-1; i>= 0; i--)
{
phrase.add(words.get(i));
}
return phrase;
}
}

A program that will let the user input a string and then output each letter on a new line

import java.util.Scanner;
public class Program3_5
{
public static void main (String[]args)
{
Scanner scan = new Scanner(System.in);
String input = new String();
System.out.println("Please enter a string: ");
input=scan.next();
int length;
length = input.length;
input.substring();
System.out.println(charAt(0));
while (length)
{
System.out.println(charAt(0 + 1));
}
}
}
I am getting an error stating that it "cannot find symbol - variable length"
I have tried numerous things yet I am having trouble getting it to work. New to Java! Thanks in advance.
For example if the user were to input: Hello There
The Output would print the letters on separate lines.
String#length() is a method, not a field, of String. You need to call the method. In Java, methods are called (or "invoked") using parentheses. So, change
length = input.length;
// to
length = input.length();
Anticipating the next compile error you see:
while (length)
won't compile in Java because length is an int, but the condition part of a while must be a boolean. I'm guessing you want to continue as long as the string is not empty, so change the while condition to be
while (length > 0)
Other problems you'll need to solve to get your code to compile:
String#substring() requires integer arguments
Also, the code will compile with the String input = new String(); but the assignment is completely unnecessary. In Java, you almost never need to new a string. Instead, use string literals.