Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / First Aid / February 2006

Tip: Looking for answers? Try searching our database.

N00b: Non-static method cannot be referenced from a static context

Thread view: 
HappyHippy - 15 Feb 2006 22:45 GMT
Background:
I've done some Java, C++ and VB in the past but nothing for a couple of
years. I'm teaching ICT (11-18 yo) and I've been asked to teach some
Java after hours from May onwards. I've ordered a few books and am using
BlueJ to refresh/relearn, but I'm rusty and when I learnt Java in
particular I either had a poor teacher or just didn't pick it up well.

The problem:
I'm making a very simple 2 class project for a coach booking system -
*Bus* and *Passenger* (code included at the bottom). I have nothing
declared as static ATM but on compiling when I try to call a method in
*Passenger*, from *Bus*, I get the aforementioned error.

Making a temp method in *Passenger*, I can get the same code to work
fine. Changing the variables to *String Static* works but feels very wrong.

I've tried various attempts to alter the code but to no avail. As a
result some of the code is inelegant (eg. tempString) but I can deal
with that later

Any help TIA

HH

In Passenger(snipping lots) I have:

public class Passenger
{
    // instance variables - replace the example below with your own
    private String fName;
    private String lName;

<snip constructors>

    public String getDetails()
    {
        return "Passenger Name: " + fName + " " + lName + "\n";
    }

And in Bus:

public class Bus
{
    public ArrayList passengers;
    private int busSize; // used to set the ArrayList size
    int booked; // count of passengers booked so far

<snip various methods>

    public void printAll()
    {
        String tempString;
        for (int i = 0; i<booked; i++) {
            tempString = Passenger.getDetails();
            // also tried passengers[i] instead of Passenger
            System.out.println(tempString);
        }
Eric Sosman - 15 Feb 2006 23:23 GMT
HappyHippy wrote On 02/15/06 17:45,:
> [... snipped for brevity and emphasis ...]
>
[quoted text clipped - 18 lines]
>          for (int i = 0; i<booked; i++) {
>              tempString = Passenger.getDetails();

   getDetails() is an "instance method," meaning that it
applies to a specific object of the Passenger class rather
than to the Passenger class as a whole.  Here, you are
trying to call it as if it were a static ("applies to
entire class") method.  You need, instead, to get hold of
an actual Passenger object and call getDetails() on that
object.

>              // also tried passengers[i] instead of Passenger

   ... and you were getting warmer, but still not quite
to the boiling point.  You were cooled off by two mistakes:

   The [i] notation applies to arrays, but `passengers' is
not an array.  It's an ArrayList, and you want to use its get()
method, as in `passengers.get(i)'.

   Once you've solved that, there's another hurdle: the get()
method returns a reference to an Object, not a reference to a
Passenger.  No doubt you filled the ArrayList by inserting
Passenger references, but when they come out again they've lost
their Passenger-ness.  You happen to know they're Passengers,
but Java doesn't -- until you tell it by using a cast:

    Passenger p = (Passenger)passengers.get(i);

This says, "Java, I have learned (from sources I am not at
liberty to disclose) that the i'th object in this list is a
Passenger, not an Integer or a JButton or whatever.  Please
recognize it as such, and afford unto it all the rights and
privileges thereunto appertaining."  Java will check to be
sure you've told the truth (if you've lied, you'll get a
ClassCastException at run-time), and will then happily use
the methods of Passenger, not just the limited set of methods
available to every Object.

   By the way, you don't really need all those intermediate
variables.  They may help you see the path a little more
clearly while you're still learning to walk, but the world-
class runners might write

    System.out.println(
       ((Passenger)passengers.get(i)).getDetails() );

The WCR's would also know that an ArrayList keeps track of
the number of elements it contains, so the `booked' variable
may be unnecessarily and redundantly superfluous...

Signature

Eric.Sosman@sun.com

HappyHippy - 16 Feb 2006 07:04 GMT
>>             // also tried passengers[i] instead of Passenger
>
>     The [i] notation applies to arrays, but `passengers' is
> not an array.  It's an ArrayList, and you want to use its get()
> method, as in `passengers.get(i)'.

I knew it was something along those lines - I just couldn't put my
finger on it

>     Once you've solved that, there's another hurdle: the get()
> method returns a reference to an Object, not a reference to a
[quoted text clipped - 4 lines]
>
>     Passenger p = (Passenger)passengers.get(i);

<snip the kind of explanation I wish they'd use in textbooks more often>

Makes perfect sense

>     By the way, you don't really need all those intermediate
> variables.  

That's what I was trying to get at with the "inelegant" comment - they
were inserted afterwards to help me try and solve the problem, but
cheers for pointing them out specifically

Thank you *very* much Eric - concise, practical help that is neither
patronising nor arrogant is pretty hard to come by. Of course the down
side is that you're going to have to put up with many more posts of a
similar nature in the near future :-D

Cheers

HH
Erich Blume - 16 Feb 2006 08:51 GMT
On 2/15/06 3:23 PM, in article dt0d5a$oen$1@news1brm.Central.Sun.COM, "Eric
Sosman" <Eric.Sosman@sun.com> wrote:
> Passenger p = (Passenger)passengers.get(i);
>
[quoted text clipped - 19 lines]
> the number of elements it contains, so the `booked' variable
> may be unnecessarily and redundantly superfluous...

Why go to the trouble and mess of casting? ArrayList supports generics. Just
make it like this:

List<Passenger> passengers = new ArrayList<Passenger>();

That way, the Java compiler will know that you're dealing with a list of
Passengers, not a list of Objects. It'll catch all errors at compile time,
not run time - something very desirable for any serious java program. Plus,
I've heard (but not seen for myself) that casting can cause very hard to
diagnose errors with instance variables being overwritten.

Also, and I don't have the first post in this series so I don't know the
seriousness of this project, but if you're writing an actual program that
will keep customer details, you'll want to stay away from ArrayLists for
things like storing customer info. ArrayLists are fine easy and lightweight
data structures for easy and lightweight applications, but you'll get
serious performance hits in serious applications. Consider using a hash,
problem of the passenger ID if they have one or else their whole name.

My guess, though, is that unless your Head of Department ;) is very
sadistic, is that (based on your difficulties) this is not a heavy-duty
application. In such a case, a hash would be overkill.

Hope that helps a bit more. Oh, and to explain generics - generics are, in a
very small nutshell, a way of telling the compiler "Ok, all I've got are
<Passenger>'s here." The class you're instantiating will have special code
to deal with that. By default, ArrayList assumes <Object> (I think - or else
1.5 has two implementations of ArrayList, one with generics and one
without), but the code is all there to take in something else.

Oh, right, and how would you use "passengers" after the generic conversion?

Passenger yourVarHere = passengers.get(#);

Rather than:

Passenger yourVarHere = (Passenger)passengers.get(#);

Signature

Erich Blume
e b l u m e @ u c s c dawt e d u

Libros virumque cano.

P.S.: I guess us Eri{c/k}{h}'s like to help.

Eric Sosman - 16 Feb 2006 17:43 GMT
Erich Blume wrote On 02/16/06 03:51,:
> On 2/15/06 3:23 PM, in article dt0d5a$oen$1@news1brm.Central.Sun.COM, "Eric
> Sosman" <Eric.Sosman@sun.com> wrote:
[quoted text clipped - 9 lines]
> Also, and I don't have the first post in this series so I don't know the
> seriousness of this project, [...]

   The first post made it clear that the project was
pedagogical: the poster has been asked to teach a class
in Java, and since his own knowledge of Java is pretty
sketchy he's diligently trying to improve it before he
faces the students.

   Under the circumstances, I think it would be wrong
to drag generics into the discussion so early.  Others
may disagree, but I think it's less confusing to avoid
them until he's gained some feeling for what goes on
"under the covers."  I'd avoid auto-boxing for the same
reason.  Walk before running; it helps keep the feet
on the ground.

   Of course, if he's using a 1.5 (or 1.6!) compiler
he'll have generics rammed down his throat whether he's
ready or not.

Signature

Eric.Sosman@sun.com

Hal Rosser - 16 Feb 2006 01:07 GMT
I recommend using JGrasp (free download at Auburn Univ) and Murach's
"Beginning Java 2" for the book to learn from, and "Head First Java" to go
along with it.
Keep BlueJ on the desktop also. With JGrasp.
HappyHippy - 16 Feb 2006 07:04 GMT
> I recommend using JGrasp (free download at Auburn Univ) and Murach's
> "Beginning Java 2" for the book to learn from, and "Head First Java" to go
> along with it.
> Keep BlueJ on the desktop also. With JGrasp.

My Head of Department (read: boss) wants me to use BlueJ specifically,
and exclusiviely, although I will look at progressing to JGrasp when
he's not looking :-)

Cheers

HH
EricF - 17 Feb 2006 05:30 GMT
>> I recommend using JGrasp (free download at Auburn Univ) and Murach's
>> "Beginning Java 2" for the book to learn from, and "Head First Java" to go
[quoted text clipped - 8 lines]
>
>HH

I'm not sure what the start of this thread is - but BlueJ is a great IDE for
newbies learning Java. You don't want to use it for any thing other than small
applications.

Eric
Roedy Green - 16 Feb 2006 14:55 GMT
>I'm making a very simple 2 class project for a coach booking system -
>*Bus* and *Passenger* (code included at the bottom). I have nothing
>declared as static ATM but on compiling when I try to call a method in
>*Passenger*, from *Bus*, I get the aforementioned error.

see
http://mindprod.com/jgloss/compileerrormessages.html#NONSTATICCANTBEREF
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.