Static method problems

  • Thread starter Stephen Marjoribanks
  • Start date
S

Stephen Marjoribanks

I am getting two compiler errors saying that I cannot reference a
non-static method from a static context. I think the problem arises from
me not entirely understanding the static keyword. My code is too long to
post, but here is an idea of the problem:


public class GMLV
{
public static void main(String[] args)
{
Application app = new Application();
}
}

class Application
{
public JPanel treePanel = new JPanel();
public JPanel sketchPanel = new JPanel();
public Jpanel mainPanel = new JPanel();
//other variables here

// constructor
Application()
{
//initialize GUI here

mainPanel.add(treePanel);
mainPanel.add(sketchPanel);
}

//other methods here including one which creates an instance of
//XMLParser

public void addComponents(JComponent tree, JComponent sketch)
{
treePanel.add(tree);
sketchPanel.add(sketch);
this.validate();
this.repaint();
}
}

class XMLParser()
{
SlopeGraphicsPanel sketch = new SlopeGraphicsPanel();
XMLTreeViewer tree = new XMLTreeViewer();

//parsing code here

Application.addComponents(tree, sketch); <<<<<<<
}

class SlopeGraphicsPanel extends JComponent
{
// graphics code here
}

class XMLTreeViewer
{
// JTree code here
}





At the moment I am getting an error pointing to where I have indicated
with <'s and it says that I cannot reference the non-static method
addComponents from a static context.
Why is this happening, and why is the context static even though I
haven't declared it to be?

Any help would be much appreciated! :)

Steve
 
D

Danno

Let me mention how I teach my students what static does. Let me use
house building as an analogy.

You have the blueprint for a house. You have the builder who takes
the blueprint and can build as many houses from that as you want. The
blueprint is a class, the builder is your VM, and the houses that the
builder builds are actual concrete objects.

So, when something is static (method, variable, initializer) that
means that it resides on the class and not on any of the objects. If
I put a static variable called count on my class (Blueprint) that means
that all objects (Houses) have access to it and it also means that my
class (Blueprint) can have access to it too. If I put a member
variable (belonging to the object) on an object, that means that that
variable belongs to the object (House) and not the blueprint. Usually,
member variables are considered attributes of the object like color.
So I can set the color or get the color of an object (House). But I
cannot get the attribute color from the class (Blueprint).

So when you "cannot reference a non-static method from a static
context" you are asking essentially asking "What color is the house?"
from the blueprint. In which the blueprint will rudely say, "WTF are
you talking about? A lot of houses get built from my design, how the
hell should I know? Go ask the houses themselves!"


In the case: Application.addComponents(tree, sketch); you are asking
the Application blueprint to add some components to the class. Since
addComponents is not a static method, the compiler is letting you know
you can't call the method on the class. You need to call this on an
object.
 
V

VisionSet

Application.addComponents(tree, sketch); <<<<<<<
At the moment I am getting an error pointing to where I have indicated
with <'s and it says that I cannot reference the non-static method
addComponents from a static context.
Why is this happening, and why is the context static even though I
haven't declared it to be?

Any help would be much appreciated! :)

Steve

addComponents is being called from a static context, namely Application.
Application is a class, a class is a static context.

new Application().addComponent(...

will fix that problem, but you *must* understand the concept of instances
and class level (ie static) members.

There is so much detail on the internet on this, and probably the number 1
question on comp.lang.java.*

Google away
 
S

Stephen Marjoribanks

VisionSet said:
addComponents is being called from a static context, namely Application.
Application is a class, a class is a static context.

new Application().addComponent(...

will fix that problem, but you *must* understand the concept of instances
and class level (ie static) members.

There is so much detail on the internet on this, and probably the number 1
question on comp.lang.java.*

Google away

Ok thank you both for your help. I worked out that I did actually have
it kinda right initially but messed up elsewhere in the code!
Thanks for your help

Steve
 
O

Oliver Wong

Danno said:
Let me mention how I teach my students what static does. Let me use
house building as an analogy.

You have the blueprint for a house. You have the builder who takes
the blueprint and can build as many houses from that as you want. The
blueprint is a class, the builder is your VM, and the houses that the
builder builds are actual concrete objects.

So, when something is static (method, variable, initializer) that
means that it resides on the class and not on any of the objects. If
I put a static variable called count on my class (Blueprint) that means
that all objects (Houses) have access to it and it also means that my
class (Blueprint) can have access to it too. If I put a member
variable (belonging to the object) on an object, that means that that
variable belongs to the object (House) and not the blueprint. Usually,
member variables are considered attributes of the object like color.
So I can set the color or get the color of an object (House). But I
cannot get the attribute color from the class (Blueprint).

So when you "cannot reference a non-static method from a static
context" you are asking essentially asking "What color is the house?"
from the blueprint. In which the blueprint will rudely say, "WTF are
you talking about? A lot of houses get built from my design, how the
hell should I know? Go ask the houses themselves!"

The example I use is a class called "Dog", and instances of the class
called "Fido", "Max", "Sparky", etc. If you ask "What biological family does
Dog belong to?", you get the answer "Canidae". If you ask "What biological
family does Fido belong to?", you also get the answer "Canidae". The
biological family is a static attribute that belongs to the class Dog.

If you ask "What colour is Fido's fur?", you get the answer "Black". If
you ask "What colour is Dog's fur?", you can't answer it, unless you know
which specific dog you're talking about. The colour of fur is an instance
attribute that belongs to each individual instance.

- Oliver
 
D

Danno

That's an awesome example. I like the house building one, because I
get to introduce the VM as the builder who takes the class (from the
classloader) and makes objects from it. Using the dog example I
would have to introduce some sort of diety as the builder of dogs in
the classroom and then it would get awkward. The bad part of my house
analogy is that my houses don't get have cool names like your dogs.

I had tried to use vehicles before but that ended up a mess. Same with
humans. I am still looking out for the greatest example to use in
class. One that would lead naturally to inheritance, polymorphism,
classloading, etc.
 
O

Oliver Wong

Danno said:
That's an awesome example. I like the house building one, because I
get to introduce the VM as the builder who takes the class (from the
classloader) and makes objects from it. Using the dog example I
would have to introduce some sort of diety as the builder of dogs in
the classroom and then it would get awkward. The bad part of my house
analogy is that my houses don't get have cool names like your dogs.

In the near future, you might be able to just hand wave and mutter
something about cloning and genetic engineering, and no one will inquire
further about who or what it is, that is making these dogs.

But you're right. The builder is a nice touch. It's just that, not
knowing anything about architectural work, I didn't automatically assume
that blueprints would omit what colour the house should be, so the "Of
course you can't ask a blueprint about the colour of the house!" wasn't
obvious to me.
I had tried to use vehicles before but that ended up a mess. Same with
humans. I am still looking out for the greatest example to use in
class. One that would lead naturally to inheritance, polymorphism,
classloading, etc.

For polymorphism, I always fall back to the classic example of drawing
geometric shapes. I suppose you could use the same "colour" idea for
explaining static with geometric shapes, i.e. "What colour is Triangle? --
Which triangle are you talking about?"

The problem with geometry though is it breaks down when you with
inheritance. Does a square have an IS-A relationship with a rectangle? Does
a rectangle have an IS-A relationship with a square? The intuitive answer is
"A square is always a rectangle, but a rectangle isn't always a square, so
therefore square should extend rectangle" leads to subclasses which don't
obey the contracts of their parents.

This might be a good way to lead into the "design pattern" of a abstract
"Foo" class, and then two concrete classes "MutableFoo" and "ImmutableFoo"
for someone who already has a good understanding of inheritance, but it's
probably confusing when teaching someone about inheritance for the first
time.

- Oliver
 
P

Patricia Shanahan

Oliver said:
In the near future, you might be able to just hand wave and mutter
something about cloning and genetic engineering, and no one will inquire
further about who or what it is, that is making these dogs.

But you're right. The builder is a nice touch. It's just that, not
knowing anything about architectural work, I didn't automatically assume
that blueprints would omit what colour the house should be, so the "Of
course you can't ask a blueprint about the colour of the house!" wasn't
obvious to me.

Maybe delivering furniture would be a better example. You can't deliver
furniture to a blueprint. You can deliver furniture to a house.
Delivering furniture is very like addComponents in the original program
- its job is to furnish the panel.

I like a lot of things about the house building analogy. It makes sense
to assume that if I ask for some service such as furniture delivery
inside my house, I mean "this" house. If I'm outside the house, I have
to say which house is to receive the delivery.

Patricia
 
A

alexandre_paterson

Hi,

I'm very surprised by this whole thread... Nobody seems to be
mentioning that "static" stuff under Java is not OO at all.

In a recent thread "Why Java is not pure object oriented", one
regular here (Chris Uppal) mentionned:

"null, all the "static crud", constructors, etc."

as clear signs that Java is not pure object oriented. And I agree
100% with that post, it's right on target.

But this doesn't mean Java has to be used or teached that way, far
from it!

Let me mention how I teach my students what static does. Let me use
house building as an analogy.

You have the blueprint for a house. You have the builder who takes
the blueprint and can build as many houses from that as you want. The
blueprint is a class, the builder is your VM, and the houses that the
builder builds are actual concrete objects.

So, when something is static (method, variable, initializer) that
means that it resides on the class and not on any of the objects.

I use static class quite often, to hide the implementation behind, say,
factories.

I do also use "static variables" for things related only to the
infrastructure, like a logger. But I would never ever use a static
method/variable for anything related to the business domain.

To me, when I see a static method it means one thing: that we're
not talking about OO.

I know that OO in itself is not precisely defined and some stuff can
be interpreted in different ways, but... Using static! Geez.

To me OO is about having abstract data type. In Java I use interfaces
to define the abstractions.

Having a static method means you're tied to a concrete implementation.

It doesn't have to be that way and there are project/codebase out there
(both public and private) that are using Java in a more OO way than
others.

I'll give an example of the way I'm doing it (and I learned it from
others) in response to the Dog / Canidae message.

See you later, Alex
 
A

alexandre_paterson

Hi Oliver,

Oliver said:
The example I use is a class called "Dog", and instances of the class
called "Fido", "Max", "Sparky", etc. If you ask "What biological family does
Dog belong to?", you get the answer "Canidae". If you ask "What biological
family does Fido belong to?", you also get the answer "Canidae". The
biological family is a static attribute that belongs to the class Dog.

I know the original poster was talking specifically about static
methods, but I can't help wonder what an comp.object regular
like you thinks about static in Java ;)


What about an interface defining some "dog abstraction":

interface Dog {
/**
* Every Dog shall belong to the Canidae family.
*/
Family biologicalFamily();
Color furColor();
}


And maybe have some private Dog implementation (never directly
exposed to the client) use a static field for the biological family...
But this is, and should be, an implementation detail.

Having an exposed static field or static method isn't OO to me
(I don't have the exact definition of OO, for there doesn't seem
to be one, but it seems to me that this "static Java features"
hasn't much to do with OO).

What if we want to add some Cats? Let's simply define a new
interface that has one method, giving back the biological family,
and make both Cat and Dog interfaces extends that interface. No
change needed in the client's code.

A static method ties you, by definition, to a concrete implementation:
it is impossible to correctly abstract the data type you need for your
objects.

I'm not a huge fan of all those animals/bank account/shape examples
that said... (probably made an overdose ;)

Most Java code I see in my day job is procedural... Most is not OO at
all. And sometimes, just sometimes, I get to use an API or work on
a codebase that "feels more OO". It's hard to describe, but to me
a static method rules the ADT part out (for it is impossible to have
the behavior clearly stated in an interface, the only way in Java to
define a pure abstraction).

Now if only some kind of DbC was possible on those interface... (I'm
using Jetbrain's @NotNull annotations and my IDE is gently preventing
lots of NPE, but that's just a hack around the non-OO null "concept".
I guess we'll see some kind of "DbC annotations" one of these days
though).

Anyway I'll digress some more: I find that teachers (and blog
writers, etc.) should state when a subject is controversial. For
example most Java "OO" books will start with an example
implicating an abstract class and hardly ever state "some person
though consider that Java wouldn't miss anything if the abstract
keyword was removed from the language" (and Gosling himself
said it, years later). It's the same for static method: some people
use them mostly to provide factories...

Curious to hear your thoughts on static / OO, Alex


P.S: I keep a "is OO possible in Java at all?" to comp.object for later
;)
 
O

Oliver Wong

Hi Oliver,



I know the original poster was talking specifically about static
methods, but I can't help wonder what an comp.object regular
like you thinks about static in Java ;)

If comp.object and comp.lang.java.programmer had a war, and I had to
choose one side, I'd probably feel more loyal to comp.lang.java.programmer.
That is I consider myself, I'm more of a Java programmer, than an OO
programmer.
What about an interface defining some "dog abstraction":

interface Dog {
/**
* Every Dog shall belong to the Canidae family.
*/
Family biologicalFamily();
Color furColor();
}


And maybe have some private Dog implementation (never directly
exposed to the client) use a static field for the biological family...
But this is, and should be, an implementation detail.

Having an exposed static field or static method isn't OO to me
(I don't have the exact definition of OO, for there doesn't seem
to be one, but it seems to me that this "static Java features"
hasn't much to do with OO).

What if we want to add some Cats? Let's simply define a new
interface that has one method, giving back the biological family,
and make both Cat and Dog interfaces extends that interface. No
change needed in the client's code.

A static method ties you, by definition, to a concrete implementation:
it is impossible to correctly abstract the data type you need for your
objects.

I'm not a huge fan of all those animals/bank account/shape examples
that said... (probably made an overdose ;)

Agreed, but recall that the original context is "Hey, I'm getting a
compile error around this keyword 'static' in Java, and I don't know why.",
not "What is the key to a good, language agnostic, OO design?"

I've been exploring more OO program designs (e.g. de-emphasizing the
concept of classes and thus the 'static' keyword, in exchange for
meta-objects), but mainly from an academic perspective. My pragmatic side is
content with Java in that it lets me write programs that do what I want them
to do without too much hassle.
Most Java code I see in my day job is procedural... Most is not OO at
all. And sometimes, just sometimes, I get to use an API or work on
a codebase that "feels more OO". It's hard to describe, but to me
a static method rules the ADT part out (for it is impossible to have
the behavior clearly stated in an interface, the only way in Java to
define a pure abstraction).

Also agreed, but note that OO is not nescessary "The One True Way" to do
things. Sometimes procedural really is the most natural way to express the
solution to a problem. One isn't good and the other is bad, or anything like
that. They're just two different tools. The more tools you have in your
toolbox and know how to solve, the more problems you can solve easily.
Now if only some kind of DbC was possible on those interface... (I'm
using Jetbrain's @NotNull annotations and my IDE is gently preventing
lots of NPE, but that's just a hack around the non-OO null "concept".
I guess we'll see some kind of "DbC annotations" one of these days
though).

I've been using assert statements for this in Java. I've recently
started playing around with AspectJ, and it seems like it'd be a good fit to
"weave in" pre-condition, post-condition and class invariant testing during
development, and then weave them out in deployed software if performance
became a concern.
Anyway I'll digress some more: I find that teachers (and blog
writers, etc.) should state when a subject is controversial. For
example most Java "OO" books will start with an example
implicating an abstract class and hardly ever state "some person
though consider that Java wouldn't miss anything if the abstract
keyword was removed from the language" (and Gosling himself
said it, years later). It's the same for static method: some people
use them mostly to provide factories...

Sometimes blog/book/whatever writers don't even know about these
controversies. I wasn't aware that Gosling had said the above, for example.
When someone asks me about a topic for which there exists controversies, I
try to make it clear that there are controversies before giving out my own
opinion. But sometimes I might have an opinion on something, talk to 50 of
my friends about it, find that they all agree with me, and just assume that
there isn't any controversy at all, when in actuallity maybe the rest of the
world (i.e. 6.6 billion people) disagrees with our opinion.

It happens when you hang out in a homogenous environment. Java
programmers tend to hang out with other Java programmers, and not, say, C++,
or LISP, or Perl programmers. So they get a "Java-centric" view of the
world, which is reinforced because everyone around them is also a Java
programmer.

That's why I've started branching out to, among other groups,
comp.object. In a thread there, with Daniel, where we're discussing
categorizing methods or functions based on their behaviour, I'm often
surprised by Daniel's views, but I assume that's because he's primarily a
C++ programmer.

- Oliver
 
A

alexandre_paterson

Re Oliver,

forgive me if the quoting is not very good: Google's Usenet
interface isn't very sophisticated :)

Oliver said:
If comp.object and comp.lang.java.programmer had a war, and I had to
choose one side, I'd probably feel more loyal to comp.lang.java.programmer.

If such a war was to happen, all that we'd have to do here is to
sit and wait while all comp.object posters kill each other ;)
Agreed, but recall that the original context is "Hey, I'm getting
a compile error around this keyword 'static' in Java, and I don't
know why.", not "What is the key to a good, language agnostic,
OO design?"

I know I know :) I specified that I was curious in what you'd
have to say about static, not criticizing your fine explanation at all!

Funny that you use the term "language agnostic" for I hesitated
about using it in my previous post :)

I've been using assert statements for this in Java. I've recently
started playing around with AspectJ, and it seems like it'd be a good fit to
"weave in" pre-condition, post-condition and class invariant testing during
development, and then weave them out in deployed software if performance
became a concern.

I'm also using assert but the thing is: you can't use it on an
interface. While annotations open up that possibility: I can
already define the object returned by an abstract method in
an interface to be @NotNull (it is not a lot, but it's a good start :)

I'm very curious about AspectJ too but... Didn't take the time
yet to look into it (I sure will one of these days though).

Sometimes blog/book/whatever writers don't even know about these
controversies. I wasn't aware that Gosling had said the above, for example.

It was a lloonngg time ago, took me some time to find back the link:

http://www.artima.com/intv/gosling34.html

Gosling: Yes -- without an inheritance hierarchy. Rather than
Gosling: subclassing, just use pure interfaces. It's not so much
Gosling: that class inheritance is particularly bad. It just has
problems.

This is not exactly what I said (one could argue Gosling is even
saying something stronger than what I did: I was just talking about
removing the abstract keyword, he's talking about removing
concrete subclassing entirely and using pure interfaces).

I'm pretty sure he said similar things more than once though.

You're point about controversies not being known is very interesting.
I guess it's just my way of "looking for information": I somehow
decide to look for the controversies, so I get to always see more than
one side of the story.

It happens when you hang out in a homogenous environment. Java
programmers tend to hang out with other Java programmers, and not, say, C++,
or LISP, or Perl programmers. So they get a "Java-centric" view of the
world, which is reinforced because everyone around them is also a Java
programmer.

:)

Point taken.

I've also got the feeling that many non-Java programmers see only
"one way" of programming in Java, maybe the most "mainstream one",
and then make conclusions on the language's inability to do this or
that cleany based on that unique way of doing things that they've
seen all too often.

So sometimes the communication is not easy.

See you soon here or on comp.object, Alex
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,678
Members
48,796
Latest member
Greg L.

Latest Threads

Top