This week's giveaway is in the Android forum.
We're giving away four copies of Android Security Essentials Live Lessons and have Godfrey Nolan on-line!
See this thread for details.
The moose likes Beginning Java and the fly likes Help! Problems with a method calling itself... Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Help! Problems with a method calling itself..." Watch "Help! Problems with a method calling itself..." New topic
Author

Help! Problems with a method calling itself...

Dois Koh
Greenhorn

Joined: Jan 23, 2009
Posts: 20
The problem is at the try and catch statement...

if there's an exception is thrown, it'll run the same method again but once it reaches the "return keyboard.nextInt();" at the try clause, an exception is thrown again without me getting the chance input any value... so it goes into an infinite loop.

Is there some fundamental thing I need to know thats the cause of this problem?

Help!! Thanks.




saurav sarkar
Ranch Hand

Joined: Jan 07, 2007
Posts: 180

Yes if you see in the exception block you are calling the same method
which is throwing the exvception.Hence the infinite loop.


Be Objectively Oriented.Explore the power of OOPs.
My Blog, Eclipse EMF Query committer.
Sagar Rohankar
Ranch Hand

Joined: Feb 19, 2008
Posts: 2902
    
    1


Which exception you are getting ? Its any time better to print stack trace and get the solution by looking at it coz Java exception are much explanatory..

One doubt Have you checked the nullablity of "keyboard" object ?

And Welcome to JavaRanch !!


[LEARNING bLOG] | [Freelance Web Designer] | [and "Rohan" is part of my surname]
Dois Koh
Greenhorn

Joined: Jan 23, 2009
Posts: 20
uhhh dont know what youre talking about Sagar.

i'm a realll beginner yeah.

anyway...

so the METHOD throws an exception?

not the statement?

sorry... this is the first time im trying to handle exceptions so i really dont know much or anything about it

Edit: btw im getting some mismatch error... Im just intentionally putting in a character instead of integer to test the programme
Sagar Rohankar
Ranch Hand

Joined: Feb 19, 2008
Posts: 2902
    
    1

Dois Koh wrote:uhhh dont know what youre talking about Sagar.


print stack trace..

If you collect them, you can find method in Exception class, like
Exception#printStackTrace();
Dois Koh
Greenhorn

Joined: Jan 23, 2009
Posts: 20
Sagar Rohankar wrote:

One doubt Have you checked the nullablity of "keyboard" object ?


when you say that are you thinking that maybe the keyboard object is retaining the char value that i've put in the first time? what exactly is nullability?

I'm really new to Java.

Sorry....
Sagar Rohankar
Ranch Hand

Joined: Feb 19, 2008
Posts: 2902
    
    1

Dois Koh wrote:
Sagar Rohankar wrote:

One doubt Have you checked the nullablity of "keyboard" object ?


when you say that are you thinking that maybe the keyboard object is retaining the char value that i've put in the first time? what exactly is nullability?

I'm really new to Java.

Sorry....


No sorry, We are here to help..

nullability means, whether the object on which you calls the method have reference to "null" object or have a valid object (one that you'll get from new Scanner()).

To check nullablity,


And had you tried to print exception stack trace ? If yes, then whats the output ??
Dois Koh
Greenhorn

Joined: Jan 23, 2009
Posts: 20
in that case, my "keyboard" object is not null.

it was created from the Scanner class - Scanner keyboard = new Scanner();

Anyway... tested and keyboard is not null.

Also...

Is this the print stack error thing?

java.lang.Exception (java.util.InputMismatchException)

Sagar Rohankar
Ranch Hand

Joined: Feb 19, 2008
Posts: 2902
    
    1

Ok, Good, Some doubts..

Dois Koh wrote:

it was created from the Scanner class - Scanner keyboard = new Scanner();



What is the input source, If you're planing to take input from keyboard, then the scanner class must take "System.in" object
Like,



Dois Koh wrote:
Is this the print stack error thing?

java.lang.Exception (java.util.InputMismatchException)



As the exception , It says "There is a mismatch, I'm expecting int value but, You entered something else..."
Dois Koh
Greenhorn

Joined: Jan 23, 2009
Posts: 20
oh yeah sorry... theres System.in i forgot to write then.

and yes... i know its supposed to be an int... ive intentionally entered a char value to trigger the exception to test the programme...

the thing is...

i wanna know why it continues to throw an exception after the first time. Apparently its because somthing that guy up there said but I dont know enough about how exceptions work to understand...


my problem is that after an exception is handled for the first time and the catch clause is triggered, the programme will loop on forever because ive got this
in the catch clause. im expecting it to run the trigger again and allow me to enter a value again but everytime it reaches the statement in the try clause, it takes it that theres an exception being thrown again...

Help!11!1/!//1
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18550
    
  40

i wanna know why it continues to throw an exception after the first time. Apparently its because somthing that guy up there said but I dont know enough about how exceptions work to understand...


Well, you tell us -- the keyboard class is your code. But if I had to guess, when your keyboard system gets something it doesn't like, it throws an exception, but it doesn't clear the buffer. It will keep throwing exceptions, until you call a nextXXX() method that will take the data from the buffer.

my problem is that after an exception is handled for the first time and the catch clause is triggered, the programme will loop on forever because ive got this


What do you mean "exception is handled"? Catching the exception, and printing a messages is not handling the exception. You have to clean up the mess (exception condition) too. In this case, you have to get you keyboard object to throw away the invalid characters.

Henry


Books: Java Threads, 3rd Edition, Jini in a Nutshell, and Java Gems (contributor)
Dois Koh
Greenhorn

Joined: Jan 23, 2009
Posts: 20
umm

keyboard is the name of an object created from the Scanner class... from the java package or something

anyway... so if it really is that... then how do I clear the buffer?
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18550
    
  40

Take a look at the JavaDocs for the scanner class...

http://java.sun.com/j2se/1.5.0/docs/api/java/util/Scanner.html

You can either use the correct nextXXX() method, to yank the bad stuff off. Or use the findXXX() method to get to the next good stuff.

Henry
Henry Wong
author
Sheriff

Joined: Sep 28, 2004
Posts: 18550
    
  40


BTW.... to use recursion to implement a retry is not a good idea. You might consider changing that, before you submit the assigment, just in case you encounter a teaching assistant in a bad mood....

Henry
Dois Koh
Greenhorn

Joined: Jan 23, 2009
Posts: 20
ookay

thanks man
Dois Koh
Greenhorn

Joined: Jan 23, 2009
Posts: 20


Hey... this is what it looks like now.
I just wanna know if this is the proper way to do it. I mean... the .next() accepts a string right (using "\r\n" as delimiters and I'm still not sure about I have to use both \r and \n but I'm just doing it without knowing for now) so since its a string, no matter what rubbish I throw at it, it would be the correct "nextXXX()" method right?

So if an exception occurs, the rubbish will be stuck in the object? If not, it'll clear automatically?

And as for the "findXXX()", you're talking about this...

String findInLine(Pattern pattern)
Attempts to find the next occurrence of the specified pattern ignoring delimiters.
String findInLine(String pattern)
Attempts to find the next occurrence of a pattern constructed from the specified string, ignoring delimiters.


Right? Don't understand what's a pattern constructed from a string though...

Anyway...

Is that the proper way to handle an/the exception? Is it working now because the keyboard.next() takes a string (so whatever rubbish value I entered would be taken) and then the buffer is cleared because its done automatically if the method is called successfully?
Dois Koh
Greenhorn

Joined: Jan 23, 2009
Posts: 20
Henry Wong wrote:
BTW.... to use recursion to implement a retry is not a good idea. You might consider changing that, before you submit the assigment, just in case you encounter a teaching assistant in a bad mood....

Henry


oh yeah and ill do something about that

Edit: oh and... why is it bad... consumes extra resources if it keeps being called kinda thing or ???
Sagar Rohankar
Ranch Hand

Joined: Feb 19, 2008
Posts: 2902
    
    1

Dois Koh wrote:

I just wanna know if this is the proper way to do it. I mean... the .next() accepts a string right (using "\r\n" as delimiters and I'm still not sure about I have to use both \r and \n but I'm just doing it without knowing for now) so since its a string, no matter what rubbish I throw at it, it would be the correct "nextXXX()" method right?

So if an exception occurs, the rubbish will be stuck in the object? If not, it'll clear automatically?


Scanner#next() ll scan anything you provided until you hit "Enter" !! And nextXXX(), If you replaced this XXX with int , float , short, primitives ,, you will find this methods specific to accept only those primitives..

Dois Koh wrote:
And as for the "findXXX()", you're talking about this...


String findInLine(Pattern pattern)
Attempts to find the next occurrence of the specified pattern ignoring delimiters.
String findInLine(String pattern)
Attempts to find the next occurrence of a pattern constructed from the specified string, ignoring delimiters.


Right? Don't understand what's a pattern constructed from a string though...


No, this method matches the particular pattern (Regular Expression) in the input string..
Sagar Rohankar
Ranch Hand

Joined: Feb 19, 2008
Posts: 2902
    
    1

Dois Koh wrote:

Edit: oh and... why is it bad... consumes extra resources if it keeps being called kinda thing or ???


Recursion is good stuff, If used carefully, otherwise its hazardous.. Its not only added the extra overhead of stack calls chain but also get stuck and may over flow. And about your problem , there is no need to make recursive call, you can use loop, any time..
Dois Koh
Greenhorn

Joined: Jan 23, 2009
Posts: 20
Sagar Rohankar wrote:
Scanner#next() ll scan anything you provided until you hit "Enter" !! And nextXXX(), If you replaced this XXX with int , float , short, primitives ,, you will find this methods specific to accept only those primitives..


I see... So using .next(); is indeed the proper way to "clear the buffer" right?

Thanks.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38100
    
  22
nextLine() may be better to clear the buffer. If you write
8374 ,dfg 304 9898.58986 98374598 dkjhfgdf
next will get 8374 and leave ,dfg (assuming you use the default delimiter-whitespace). If you use nextLine you will get the remainder of the line passed, then you can ignore it and start a new input on the new line.
Dois Koh
Greenhorn

Joined: Jan 23, 2009
Posts: 20
Campbell Ritchie wrote:nextLine() may be better to clear the buffer. If you write
8374 ,dfg 304 9898.58986 98374598 dkjhfgdf
next will get 8374 and leave .dfg (assuming you use the default delimiter-whitespace). If you use nextLine you will get the remainder of the line passed, then you can ignore it and start a new input on the new line.


thanks for the heads up

I'm using the delimiter as "\r\n" though so no problems there.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38100
    
  22
If you use that delimiter, you will lose portability; it will only work correctly on DOS/Windows. And it won't work the way we are used to.

The default delimiter is whitespace, so you can write
1 2 3 4 5 6 7
and call nextInt() seven times getting 1 2 3 4 5 6 7 in turn. Or you could call next() seven times getting "1" "2" etc etc. Or even nextDouble() getting 1.0 2.0 3.0 etc. Or any combination. Or you can call nextLine() halfway through the line, getting a String something like "4 5 6 7" and then you could discard that String and go to the next line.

Go to the regular expression classes, and (I think in the Pattern class, but I'm not sure) you can find a complete list of line end characters. There are about 6 or 7 of them. You can put them into a regular expression. You can find a section about regular expressions in the Java Tutorials. I think you end up with something like [\r\n\f]+ only you have to write "[\\r\\n\\f]+" to maintain the escapes. If I remember correctly, and I might be mistaken, that allows you to select 1 or more of those characters in any order. I think, but haven't checked recently, that the delimiter in Scanner is a String representing a regular expression, so that would give you better control of line ends on all OS.

There are quite a lot of Java methods which take a regular expression as their argument; you can usually tell because it says String regex in the API documentation. If it is an ordinary String it usually says String s or similar.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38100
    
  22
myself wrote:There are quite a lot of Java methods which take a regular expression as their argument; you can usually tell because it says String regex in the API documentation. If it is an ordinary String it usually says String s or similar.
I have found the appropriate documentation: Scanner and Pattern.

And the Scanner#useDelimiter method calls its parameter "pattern!"
Dois Koh
Greenhorn

Joined: Jan 23, 2009
Posts: 20
Go to the regular expression classes, and (I think in the Pattern class, but I'm not sure) you can find a complete list of line end characters. There are about 6 or 7 of them. You can put them into a regular expression. You can find a section about regular expressions in the Java Tutorials. I think you end up with something like [\r\n\f]+ only you have to write "[\\r\\n\\f]+" to maintain the escapes. If I remember correctly, and I might be mistaken, that allows you to select 1 or more of those characters in any order. I think, but haven't checked recently, that the delimiter in Scanner is a String representing a regular expression, so that would give you better control of line ends on all OS.

There are quite a lot of Java methods which take a regular expression as their argument; you can usually tell because it says String regex in the API documentation. If it is an ordinary String it usually says String s or similar.


Woahh you really lost me there.... alotta terms I don't understand... Anyway since I'm just doing an assignment for my object oriented programming class I'm guessing I won't need to bother about portability (though itd be good to know)

Honestly I don't even know why I'm using \r\n as the delimiter. I mean I understand that its usually whitespace but then I've been thinking that newline or line feed or whatever you call it (\n) would be enough... but there were some problems I can't remember... anyway I ended up using carriage return & line feed. If I'm not wrong, carriage return is when the cursor is pushed all the way to the left, right? when you hit the return key. But windows is both return and enter or something and all that complicated stuff that I don't understand yet so...

anyway nevermind about that thanks for the help
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38100
    
  22
No, you never use a carriage return key any more, only "enter". On old teleprinters (I remember using one in 1971) you had a "CR" ("carriage return", not "Campbell Ritchie" ) key and an "LF" ("linefeed") key, and had to push CR-LF at the end of a line.
The CR took the print head back to the left, and the LF moved the paper up one line, so it is now often called "newline."

The characters emitted were (as far as I know) CR = (char)0xd which we usually express as \r and LF = (char)0xa which we usually express as \n. Different operating systems use different characters as their line ends; Unix and Linux and newer Macs use \n only, older Macs use \r only, and Windows/DOS uses what I remember from 38 years ago: \r\n. So using "\r\n" means you will only detect line ends on Windows/DOS computers.

You need to mention in your submission that you have discussed the case on JavaRanch and people suggested you used a regular expression to improve portability. If I were marking that would gain you an extra mark. But I'm not marking!

I think "[\r\n]+" will divide your input at the end of each line and miss out blank lines; "[\r\n]" will divide at the end of each line and record empty lines. So if you are trying to read an int you would need to push the enter key after the number. Also next() and nextLine() would behave similarly to each other.

If you really don't know why you chose that delimiter, I suggest you revert to the default delimiter of whitespace.
As I said you can writeand it will accept 1 2 3 or
1
2
3
as input, with exactly the same result, if you use "whitespace" as the delimiter.

I suggest you write yourself a test class, which repeatedly prints "Please enter three numbers:" and then reads the three numbers from the keyboard and prints them out, and different combinations.
Try some if testsKeep doing this until you get familiar with Scanner. Find out what happens if you need three numbers and enter "1 2 3 4". Find out what happens to the 4. Find out how to use Scanner#nextLine() to get rid of the 4. Try changing the delimiter to "[\r\n]+" (maybe spelt "[\\r\\n]+" to maintain escapes), and see what the difference is.

Then you will be familiar with the vagaries of Scanner and can use it confidently.
Dois Koh
Greenhorn

Joined: Jan 23, 2009
Posts: 20
Campbell Ritchie wrote:No, you never use a carriage return key any more, only "enter". On old teleprinters (I remember using one in 1971) you had a "CR" ("carriage return", not "Campbell Ritchie" ) key and an "LF" ("linefeed") key, and had to push CR-LF at the end of a line.
The CR took the print head back to the left, and the LF moved the paper up one line, so it is now often called "newline."

The characters emitted were (as far as I know) CR = (char)0xd which we usually express as \r and LF = (char)0xa which we usually express as \n. Different operating systems use different characters as their line ends; Unix and Linux and newer Macs use \n only, older Macs use \r only, and Windows/DOS uses what I remember from 38 years ago: \r\n. So using "\r\n" means you will only detect line ends on Windows/DOS computers.

You need to mention in your submission that you have discussed the case on JavaRanch and people suggested you used a regular expression to improve portability. If I were marking that would gain you an extra mark. But I'm not marking!


THANKS. That really cleared up a lot. Though I still don't know why the teacher said to use "\r\n" if we can just use "\n". When I asked about the what exactly they were she said something about how "you can't just make a newline without carriage return" or something like that... I don't know... Anyway... I'm still confused about that and what exactly the "enter/return" key does on the Windows keyboard (I'm guessing it's different with Macs?). It's like joined into one key on this keyboard and theres a separate "enter" key at the bottom right.


I think "[\r\n]+" will divide your input at the end of each line and miss out blank lines; "[\r\n]" will divide at the end of each line and record empty lines. So if you are trying to read an int you would need to push the enter key after the number. Also next() and nextLine() would behave similarly to each other.


Oh yeah... I was initially using nextLine() but when I did something like



It seemed to take record a straightaway without me putting in any input (typing something and pressing enter) and then it would start waiting at b...
So I ended up using next() with the "\r\n" delimiters.

It like takes the System.out.print(xxxxxx); statement or something... I dunno.


If you really don't know why you chose that delimiter, I suggest you revert to the default delimiter of whitespace.
As I said you can writeand it will accept 1 2 3 or
1
2
3
as input, with exactly the same result, if you use "whitespace" as the delimiter.

I suggest you write yourself a test class, which repeatedly prints "Please enter three numbers:" and then reads the three numbers from the keyboard and prints them out, and different combinations.
Try some if testsKeep doing this until you get familiar with Scanner. Find out what happens if you need three numbers and enter "1 2 3 4". Find out what happens to the 4. Find out how to use Scanner#nextLine() to get rid of the 4. Try changing the delimiter to "[\r\n]+" (maybe spelt "[\\r\\n]+" to maintain escapes), and see what the difference is.

Then you will be familiar with the vagaries of Scanner and can use it confidently.


Thanks a lot man! That really clared a lot of things up...

I went to do the test and stuff and I guess I roughly understand now... the tokens and stuff...

By the way... this means I can actually just use the hasNextInt() to do the validation right? Instead of using try and catch like what I was trying to do...


(maybe spelt "[\\r\\n]+" to maintain escapes)


Oh and whats an 'escape' and why do you have [ ] brackets as part of the delimiter... I just do it like this... Whats the brackets for?
Dois Koh
Greenhorn

Joined: Jan 23, 2009
Posts: 20
Hi...



I've rewritten it to this..



And it seems to only work properly when I use "\r\n" for the delimiters.

If I use \r alone or \n alone .nextInt() would throw an exception... Like the scanner is taking a line or something as input... I don't know... what is \r for!?!?!!11! newline is a character as well right? is \r a character!? ahhhhhh
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38100
    
  22
It's good when you make progress, isn't it .

The [] in the regular expression allows the computer to choose any of the contents, so [\r\n]+ means \r or \n or \r\r or \n\n or \r\n or \n\r or \n\n\n . . .
Dois Koh
Greenhorn

Joined: Jan 23, 2009
Posts: 20
ok thanks!

but \n\n\n is only if theres a '+' right? [\r\n]+<<< that plus
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38100
    
  22
Yes, as Rob Prime pointed out to me a few weeks ago, you can avoid Exceptions with judicious use of Scanner#hasNextInt() or similar. You can even put that into a loop which tests whether the number has been entered.
Yes \r is a character. I told you yesterday, it is (char)0xd.
If it only works with \r\n that is because you are using Windows; if you only use \r or \n as a delimiter, then you are trying to parse \n123 or 123\r into an int but it also means it won't work on a Linux box where the line end is usually \n.

I would prefer to see the loop without a return statement and a boolean local value for whether you have found the int, then the return statement at the end of the method.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38100
    
  22
As far as I can remember [\r\n] (or [\n\r]) will only match one \r or one \n.
You may need to write \\ instead of \ in Java code because \ starts an escape sequence.
As far as I can remember, [\r\n]+ with the + will match all the things I said earlie, yes.

There is lots about regular expressions in the Java Tutorials.
Dois Koh
Greenhorn

Joined: Jan 23, 2009
Posts: 20
I see... thanks again.

Campbell Ritchie wrote:
I would prefer to see the loop without a return statement and a boolean local value for whether you have found the int, then the return statement at the end of the method.


Why so? Is it bad to return in the middle of a method or loop??

You mean to do it like this right?
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38100
    
  22
At a very quick look at your loop, yes, that is what I meant.
Some people will disagree with me, but I like structured programming and one of the rules of structured programming is that each method/loop/selection should have a single exit. A "break" or "return" in a loop provides multiple exits.

Look in our style guide, which is just a suggestion, but was obviously written by another lover of structured programming; it says to avoid break and multiple exit points.
Dois Koh
Greenhorn

Joined: Jan 23, 2009
Posts: 20
Campbell Ritchie wrote:At a very quick look at your loop, yes, that is what I meant.
Some people will disagree with me, but I like structured programming and one of the rules of structured programming is that each method/loop/selection should have a single exit. A "break" or "return" in a loop provides multiple exits.

Look in our style guide, which is just a suggestion, but was obviously written by another lover of structured programming; it says to avoid break and multiple exit points.


I see... I'll definitely look into it. Thanks.

And I'll try my best to practice "structured programming".

Edit:
3.3 - Initialization

Declare variables as close as possible to where they are used.



Oh wow I expected people to prefer you (I mean if its more than one person coding/ sharing code) to declare everything at the top... I prefer to declare them as close as possible to where they are used as well!
Sagar Rohankar
Ranch Hand

Joined: Feb 19, 2008
Posts: 2902
    
    1

Dois Koh wrote:
3.3 - Initialization

Declare variables as close as possible to where they are used.





But this isn't possible in C,

And If you are following this Style convention here on JavRanch, then it suggest to do not use do... while loop., but its a suggestion after all.
And I'm pretty excited with your progress.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38100
    
  22
Sagar Rohankar wrote: . . .

But this isn't possible in C,

And If you are following this Style convention here on JavaRanch, then it suggest to do not use do... while loop., but its a suggestion after all.

And I'm pretty excited with your progress.
Java isn't C and it isn't C++; lots of experienced people get into no end of difficulty with that. They seem to think that because Java syntax looks like C syntax, it means the same thing.

Agree about the do loop. As I said, the style guide is a suggestion, not an instruction, and I would happily use a do loop. Of course, you can easily change that to a while loop:-

while (!valid) . . .

Agree about the last comment; that last loop of yours shows you know how to program
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 38100
    
  22
Dois Koh wrote:Declare variables as close as possible to where they are used.
That means local variables. It is still correct to declare all the fields together at the very beginning (or the very end) of the class. Remember fields can be used anywhere in the class, so "close to where they are used" doesn't mean much.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Help! Problems with a method calling itself...
 
Similar Threads
two simple troubles.
Java Classes
Add an exception for divide by zero to my fraction class
Help Debugging my TCP client server program to solve the producer consumer problem
my last question for this program.