Meaningless Drivel is fun!*
The moose likes Beginning Java and the fly likes simple method question Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "simple method question" Watch "simple method question" New topic
Author

simple method question

Justin Johnson
Greenhorn

Joined: Sep 12, 2011
Posts: 10
I have successfully created a class HockeyTeam.java that includes the method printTeamStats() to print out various stats of a hockey team that I build. So when I place the line "Penguins.printTeamStats();" at the end of this program it works. However, I'm having trouble with what seems like a simple task of building a method to print out the stats of the division, meaning just using printTeamStats() for each team in the division with a name like "printAtlanticStats()". I'm usually getting a "cannot be resolved" error.




Just to clarify I want something like the below to work but it doesn't.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Here are a few helpful hints to more clearly communicate your qeustion, so you cat get better help sooner. (Click the links for detials.)

1. UseCodeTags so your code will be easier to read.

2. Provide an SSCCE that includes everything needed to demonstrate the problem, and nothing more. For instance, you would need to include your printAtlantic() method and show how you're calling it. You would *not* include a printCentral() method which just does the same thing for another division. We should be able to copy/paste your code and get the same results you do.

3. TellTheDetails. Paste in the exact, complete error message, and indicate clearly which line is causing it.

Good luck!
Willie Tsang
Greenhorn

Joined: Nov 20, 2011
Posts: 24
did you define printTeamStats()?
fred rosenberger
lowercase baba
Bartender

Joined: Oct 02, 2003
Posts: 11477
    
  16

I've added the code tags for you...next time, just highlight your source and click the 'code' button - just like you want to make something bold or italic.

I think the problem with your code as-is is that the Penguins object (for example) is local to the main method...so when you call the printAtlantic() method, it is out of scope. The simplest way to fix this would be to declare it as a member variable (I think this will work):



However, this is a TERRIBLE design for an OO project. What if a new hockey team come into existence? What if a team changes their name?

What you really want to do is create a collection of teams...you could have a collection of NorthEast teams and a collection of Atlantic teams. Then, you define a method that iterates through each element of the list and prints the team stats for each element in the list.

There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors
Gary Deer
Greenhorn

Joined: Aug 20, 2010
Posts: 26

You're dealing with a collection without using an array or any other kind of list object.

It's also a scope issue. The Main method is the only one that knows what a penguin or a Flyer is. Not only that, but it only knows a team name after it is explicitly declared. So even if you put a method in Main that call the Penguin.print, Flyers.print, etc. it won't know what you're talking about since the objects aren't created until run time.

Think about it like this, what if even YOU didn't know what the team names were? Let's say you were told to make a program that took user input; you would be forced to collect the team stats, organize them, and then print them out.

Maybe it's time to go back to the drawing board on this one. As it was said before, if you had to add teams or change names, you would have to edit code directly.

To keep the design the way it is I would suggest using an array, adding the division as a member variable, and using a for loop to iterate over the teams printing those whose division variable == "Atlantic". I'm just going off the top of my head here, so there might be scoping issues with that solution too, but you might think of something else while trying to implement that.

This is also a good example why OO design is best because if you wanted to expand this program to add team member stats you would have to redesign it anyway.

This program would be good for objects that are temporary. But even still you would have issues trying to create a method that printed stats for objects that are yet to be created.

This is what fred was talking about; if you had Penguins, Flyers, etc. declared as variables as he showed you, then the computer will know at compile time who Penguins, Flyers, etc. are, so that when it's trying to compile "Penguings.print..." it won't get confused.


When all you have is a hammer, everything looks like a thumb.
Justin Johnson
Greenhorn

Joined: Sep 12, 2011
Posts: 10
Thanks Fred, I did what you suggested but now have a different error. I feel I am not properly using the static modifier somewhere but while I try different combinations I receive a variety of errors. I realize this probably isn't the best way to construct a formal project, but I just threw this together and am wondering what I'm doing wrong.

Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Cannot make a static reference to the non-static method printAtlantic() from the type LeagueStats



The following is my complete code for HockeyTeam.java which works, but I'm including it here if someone wants to try and compile the program themselves.

Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

You could make printAtlantic static. That would get rid of one compilation error. But that's just a non-OO hack. I hope you will not choose to continue down that path.
Justin Johnson
Greenhorn

Joined: Sep 12, 2011
Posts: 10
Jeff Verdegan wrote:You could make printAtlantic static. That would get rid of one compilation error. But that's just a non-OO hack. I hope you will not choose to continue down that path.


I tried that and get a different error

Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Cannot make a static reference to the non-static method printAtlantic() from the type LeagueStats
Matthew Brown
Bartender

Joined: Apr 06, 2010
Posts: 4464
    
    8

Justin Johnson wrote:I tried that and get a different error

Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Cannot make a static reference to the non-static method printAtlantic() from the type LeagueStats

That's the same error - you sure you added static where Jeff suggested? It's happening because the main() method is static, and printAtlantic() isn't. Non-static methods belong to specific instances of the class, so as it stands printAtlantic() must be called on a specific instance.

But fix that and you'll run into a different problem. All your HockeyTeam class members are also non-static, so they can only be called from a non-static context, or via an instance of the class. And they're all null anyway, because you've initialised local variables in your main method instead.
Justin Johnson
Greenhorn

Joined: Sep 12, 2011
Posts: 10
Gary Deer wrote:
To keep the design the way it is I would suggest using an array, adding the division as a member variable, and using a for loop to iterate over the teams printing those whose division variable == "Atlantic". I'm just going off the top of my head here, so there might be scoping issues with that solution too, but you might think of something else while trying to implement that.


Thanks, this is definitely an approach I would be willing to take. Just to clarify, teams and divisions are set in stone and will always be held constant for the scope of this program. I just want a small program to mess around with stats a little, this isn't something I'm looking to have for years.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

I think you're falling into the trap of, "What do I type to make the compiler errors go away?" That might get you past a few errors now, to where your program compiles, but it won't help you learn the language at all, and you'll just end up back here with more questions the next time you have a syntax error.

I think it's time to take a step back and actually learn and understand the concepts of static and non-static, so you'll be able to use them appropriately in your design. Then, you won't get these compiler errors, or if you do, it will come down to a simple typo that you'll know immediately how to fix, or as a flag to you that you need to go back and double-check your design.

First, you need to understand the difference between a class and an object. I'm going to assume you do, and if not, I'm going to leave it up to you to reasearch it.

Static methods and variables are those that apply to the class as a whole, not to any specific instance (object), whereas non-static methods and variables only make sense when you have an instance of the class.

For example, let's say you have a Student class. That Student class might have non-static variables int id and String name, and a non-static print() method that displays the id and name. You can only access the id and name variables, and can only invoke the print() method, when you have a particular Student object to which they apply. Now let's say you want to automatically generate sequential IDs as you create Students. You might add a static int variable nextId that you increment each time a Student is created. You could include a static getNextId() method that will tell you what the next ID will be, if you need to know that for some reason. The nextId variable and getNextId() method apply to the Student class as a whole, not to any particular Student object.

Do you understand this? Do you understand why you couldn't just call your printWhatever() method from main? If you do, you should be able to fix those errors in your code without any further problems.

If you have any questions about the above or anything is not crystal clear, I strongly urge you to implement the Student class I just described. The whole thing should be no more than about 10 lines. And maybe you could add a main method that creates a couple Students, prints them out, and prints out the next ID.

Seriously. Do it. It's much easier to learn a concept by writing, debugging, and executing an extremely tiny program than a larger one.
fred rosenberger
lowercase baba
Bartender

Joined: Oct 02, 2003
Posts: 11477
    
  16

Justin Johnson wrote:(The specs)...are set in stone and will always be held constant for the scope of this program. I just want a small program to mess around with stats a little, this isn't something I'm looking to have for years.

Such are the exact words spoken by every project manager I've ever worked for, and it has NEVER held true. I cannot tell you the number of times I've had to fix programs that were 'quick and dirty', one-off jobs that were still hanging around years later.

Besides, if you are learning java, shouldn't you learn the RIGHT way to do it?
Justin Johnson
Greenhorn

Joined: Sep 12, 2011
Posts: 10
Jeff Verdegan wrote:
I think it's time to take a step back and actually learn and understand the concepts of static and non-static, so you'll be able to use them appropriately in your design.


Yeah I definitely have to do this, I originally simply created the program for just printing out stats of one team and then later I decided I wanted to include the team within divisions. It looks like arrays is the best route to go about doing this (I haven't gotten to the chapter on arrays yet though).

In the meantime though, if there is a quick fix available for my program above what is it? So far I've posted all my code and none of the suggestions given so far have worked. Are they working for anyone else?
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Justin Johnson wrote:
In the meantime though, if there is a quick fix available for my program above what is it?


There almost certainly is. I'm sure not gonna give it out though. I don't like encouraging bad habits.

So far I've posted all my code and none of the suggestions given so far have worked. Are they working for anyone else?


If they didn't work, then you didn't follow them correctly. If you show your current code (or better a version stripped down to an SSCCE), then somebody should be able to point out where you went wrong.
Justin Johnson
Greenhorn

Joined: Sep 12, 2011
Posts: 10
Jeff Verdegan wrote:
Justin Johnson wrote:
In the meantime though, if there is a quick fix available for my program above what is it?


There almost certainly is. I'm sure not gonna give it out though. I don't like encouraging bad habits.

So far I've posted all my code and none of the suggestions given so far have worked. Are they working for anyone else?


If they didn't work, then you didn't follow them correctly. If you show your current code (or better a version stripped down to an SSCCE), then somebody should be able to point out where you went wrong.


Yeah I followed a lot of variations of the quick fix advice given (starting with simply adding the static modifier to printAtlantic() )and it still doesn't work, but you're right, getting back to the basics is the way to go. I appreciate your help and thanks for trying.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8208
    
  23

Justin Johnson wrote:Yeah I followed a lot of variations of the quick fix advice given (starting with simply adding the static modifier to printAtlantic() )and it still doesn't work, but you're right, getting back to the basics is the way to go. I appreciate your help and thanks for trying.

Justin, you are a man after my own heart (not literally, you understand). I am a Canucks fan and a stats major, and a Java evangelist; and can therefore not think of anything better than to lead a fellow hockey fan to the path of Java enlightenment.
And I therefore say unto you, my son: Look to your classes; they are the source of all true stats, and will lead you to righteousness: the Player, the Team, the Conference, The Division, The Cup.

These are the source of salvation - Halleluyah - and they will guide you to glory. Forsake the ways of the String; they are the work of the Devil (not a class) and will lead you down the stony path to frustration and misery. You may have to deal with them, but they are false; sanctify them, convert them, turn them to them to the ways of statistical glory - numbers - and never let the shade of the Devil (the String) darken the inner sanctum of your holy statistical order.

Oh, and while you're at it, have a look at the Java Collections Framework. All those classes that you're about (hopefully) to define could probably do with some.

Winston

fred rosenberger
lowercase baba
Bartender

Joined: Oct 02, 2003
Posts: 11477
    
  16

I'll help you, because there is an important lesson to learn aside from the collection issue...and that is the static vs. non-static thing. Just looking at a simplified version of your "LeagueStats:



There are a few things to note here. First, 'static' means you can call the method or use the variable regardless of whether you create an instance of object or not. It makes no sense to call 'getName' on a Dog if you don't actually HAVE a dog. However, calling the sqrt(7.0) DOES make sense, even if you don't have a Math object.

So, on line 3, you declare a member variable. This variable will ONLY exist if you create a LeagueStats object.

on line 5, you declare a static main method. You can call this without creating a LeagueStats object. That makes sense... You have to start somewhere, and you can't have an object before you start.

Now it gets confusing...on line 6, you declare ANOTHER reference variable called "Penguins" - you now have (potentially) TWO things called "Penguins". I say potentially because until we create an object, the one declared on line 3 doesn't exist.

So then on line 7, you call the printAtlantic method, which is NOT static. But since we have never created a LeageStats object, we can't actually call it. And THAT is what the error says.

so one solution is to make the method static:


If you do this, you'll get a new error:

C:\slop>javac LeagueStats.java
LeagueStats.java:10: non-static variable Penguins cannot be referenced from a static context
Penguins.printTeamStats();

Ok...the 'static context' refers to the fact that your method printAtlantic is static. the non-static variable it refers to is the one on line 3. Huh? What about the one on line 5? Well that one is out of scope. again, you may ask "huh?"

Scope refers to where a variable can be seen, or where it exists. Since you declared "HockeyTeam Penguins" inside the main method, it can ONLY be seen inside the main method. So when you get down into the printAtlantic method, it can't see that one. It goes to the only possible thing it can see - the Penguins defined on line 3. But that is not static - it can only be seen if we create an object, and we haven't, so IT doesn't exist.

So what do we do? we have many options, but i'd probably go with making a LeageStats object:


What's going on here? The first thing I do in my main is create an instance of the object LeagueStats (line 6). Now that object has a Penguins reference in it. That is currently not pointing to anything, so I create a HockeyTeam and have my league.Penguins reference point to it (line 7).

Since my printAtlantic method is non-static, I can only call it on my instance, which I do on line 8.

Now LeagueStats is non-static - it only works when I have an instance, which I do. My instance has a HockeyTeam (called Penguins). My HockeyTeam has a non-static method I can call to print the stats.

WHEW....

There is a LOT here. Please read it 10 or so times, and really try to digest it. this may seem like overkill, but it is critical for good development you understand these things.

I hope it helps.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18902
    
    8

Not to mention that the Son (Sidney Crosby) has returned to lead us (or at least the NHL discipline committee) back into the paths of righteousness.
Gary Deer
Greenhorn

Joined: Aug 20, 2010
Posts: 26

If you've posted all the code that you've written so far, then I'll be happy to take a stab at compiling and running it tomorrow. Since you're trying to write a program with the limited amount of Java knowledge you have right now, it will be interesting to see you take this one and evolve it whenever you learn new information (which is why I encouraged taking a broadview approach.)

Edit: everything below this line has been said before because I took too long posting-------------------------------------------------------------

To translate your problem into Jeff's Student example, lets say you had a student class with an ID and name.
Since the ID is automatically generated by the code it's static because the computer already knows at compile time what the value of this variable will be at any moment since it's just (1...n+).

What it doesn't know at compile time is what the student's names are going to be. So if you hard coded 2 students and then a print next id, the reason it will compile is because the computer is aware of what that value will be (3). However, if you told it to do Sally.printName(); the compiler will wonder who sally is because she hasn't been created yet even if she's hard coded in main().

However, if you initialize sally then at least the computer knows about her.

This is done by just typing Student Sally; outside of main(). (Now Sally is on the stack somewhere; an object is born)

not the most elegant solution, but at least the computer will trust you when it sees you've hard coded the print method with the object.


Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Gary Deer wrote:
Since the ID is automatically generated by the code it's static because the computer already knows at compile time what the value of this variable will be at any moment since it's just (1...n+).


No. Definitely not. "Static" has nothing to do with knowing a value at compile time, and the compiler definitely doesn't know anything about any values for the static variable in my example. It simply means, as I stated, that something is associated with the class as a whole, not with any specific instance.

However, if you initialize sally then at least the computer knows about her.

This is done by just typing Student Sally; outside of main(). (Now Sally is on the stack somewhere; an object is born)


No. That doesn't initialize anything, and it doesn't put anything on the stack. If it's "outside of main", then it's a member variable, and except in the cases where the JVM implements escape analysis and creates short-lived objects on the stack, all member variables are part of their respective class definitions or instances, and hence go on the heap with their respective owning objects or classes.

not the most elegant solution, but at least the computer will trust you when it sees you've hard coded the print method with the object.


This really doesn't mean anything at all and should be ignored.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8208
    
  23

Jeff Verdegan wrote: "This really doesn't mean anything at all and should be ignored."

Seems to me we're arguing semantics, and not Justin's intention, which is (as I understand it) to collect hockey stats.

@Justin: My first post was flippant, but its intentions were good. Java is an Object-Oriented language, so it works best when it has objects to work with. There's nothing to stop you from making a class for anything that you want to keep stats on, be it a Player, a Conference or a Cup (or indeed a Team). How you set them up and what stats you keep are up to you, but my advice: do it.

Winston

Sorry guys, for some reason, the '[quote]' brackets aren't working.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

Winston Gutkowski wrote:@quote=Jeff Verdegan - "This really doesn't mean anything at all and should be ignored."

Seems to me we're arguing semantics, and not Justin's intention, which is (as I understand it) to collect hockey stats.


I really don't know what he was trying to say there, but I assumed it was follow-on from the incorrect "compiler knows about static variables' values" comment. I'm assuming the OP is trying to learn Java, so I'm just hoping to redirect him away from sloppy terminology and inaccurate explanations.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39828
    
  28
Winston Gutkowski wrote: . . . Sorry guys, for some reason, the '[quote]' brackets aren't working.
They worked all right when I went back to your post and tried them.

I hope I haven’t trodden on your toes by editing your tags; if I have, then I am sorry.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 8208
    
  23

Campbell Ritchie wrote:
Winston Gutkowski wrote: . . . Sorry guys, for some reason, the '[quote]' brackets aren't working.
They worked all right when I went back to your post and tried them.

I hope I haven’t trodden on your toes by editing your tags; if I have, then I am sorry.

Nope; and thanks. Dunno what it was , but I couldn't separate the quote from the first sentence. Seems fine now, thanks to you.

Winston
Gary Deer
Greenhorn

Joined: Aug 20, 2010
Posts: 26

Hate to dig up an old thread, but when I read about the NHL conference realignments I immediately thought of this thread.

 
 
subject: simple method question