Static Versus Non Static

R

Ravi Shankar Nair

Dear all,

Today I was part of a fruitful discussion. But that left me in mere
oblivion.

A static method cannot access non static members of the class. Well, thats
fine and clear.

But a non static method ( or instance method) can access a static variable
in Java!!!

But a non static method is basically doing an instance service. Hence how
come instance service be allowed to manipulate a class variable ( or static
variable ) ? Surely C++ throws an exception, and is that not a drawback in
Java language syntax?

Or anyone please suggest a situation where instance service has to
manipulate a class variable ? Constructor makes sense, and let constructors
be the only functions which has the power to do both instance and class
service. But other than constructors, every other instance method should be
disallowed to use a class variable, right?

Please share your comments, thanks. Just for the discussion and value added
remarks, I am keeping the post to comp.object as well.

Regards,
Ravi
 
B

bikemh

Ravi said:
A static method cannot access non static members of the class. Well, thats
fine and clear.

that's not necessarily true. It's merely a matter of practicality, as
to whether the instance member can be pointed to or not. Consider this:

public class A {

int y;

public static void main(String[] args) {
A a = new A();
y = 2; // this makes no sense - which y is pointed to?
a.y = 2; // this does not produce a compiler error
}

}

But a non static method ( or instance method) can access a static variable
in Java!!!

But a non static method is basically doing an instance service. Hence how
come instance service be allowed to manipulate a class variable ( or static
variable ) ?

because it's useful :) so why forbid it?
Surely C++ throws an exception, and is that not a drawback in
Java language syntax?

Or anyone please suggest a situation where instance service has to
manipulate a class variable ?

sure, let's say that each object increments a counter when it performs
its task. It makes sense for the counter to be static, because
therefore it is easily referenced from each object.
 
O

Oliver Wong

[...]
A static method cannot access non static members of the class. Well, thats
fine and clear.

But a non static method ( or instance method) can access a static variable
in Java!!!

But a non static method is basically doing an instance service. Hence how
come instance service be allowed to manipulate a class variable ( or
static variable ) ? Surely C++ throws an exception, and is that not a
drawback in Java language syntax?

Does C++ throw an exception? I'd be surprised. Did you actually try
this?
Or anyone please suggest a situation where instance service has to
manipulate a class variable ? Constructor makes sense, and let
constructors be the only functions which has the power to do both instance
and class service. But other than constructors, every other instance
method should be disallowed to use a class variable, right?

We're implementing an XML view for one of our data structures. We use
the Saxon XQuery library to be able to perform queries on XML documents. The
Saxon library expects every XML node to implement the INode interface, and
one of the methods in INode is getName():

public interface INode {
/**
* Returns the name of the node. For example, the
* name of the node
* <foo>Hello World!</foo>
* is "foo".
*/
public String getName();
}

So our data structure has a bunch of classes, and the instances of these
classes will always return the same name for the INode interface.

public class EmployeeNode implements INode {
public final static XML_NODE_NAME = "Employee";

public String getName() {
return XML_NODE_NAME;
}
}

- Oliver
 
T

Tor Iver Wilhelmsen

Ravi Shankar Nair said:
But a non static method ( or instance method) can access a static variable
in Java!!!

Yes, because it's accessible. And instance sees its class, a class
does not see its instances.
But a non static method is basically doing an instance service.
Hence how come instance service be allowed to manipulate a class
variable ( or static variable ) ?

Because static data is a good place for several instances to share
data among themselves.
Surely C++ throws an exception, and is that not a drawback in Java
language syntax?

Really? The following compiles fine in GCC:

#include <iostream>
using namespace std;
class foo {
public:
static int staticValue;
};

int main(int argc, char** argv) {
foo object;
// Modify via instance
object.staticValue = 42;
// instance then class access to static field
cout << object.staticValue << " " << foo::staticValue << endl;
return 0;
}

My GCC environment is badly set up, however, so the linker failed; so
I cannot run it to test.
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Ravi said:
But a non static method ( or instance method) can access a static variable
in Java!!!

But a non static method is basically doing an instance service. Hence how
come instance service be allowed to manipulate a class variable ( or static
variable ) ? Surely C++ throws an exception, and is that not a drawback in
Java language syntax?

Java allows it. C++ allows it. C# allows it.

100% consistency.
Or anyone please suggest a situation where instance service has to
manipulate a class variable ? Constructor makes sense, and let constructors
be the only functions which has the power to do both instance and class
service. But other than constructors, every other instance method should be
disallowed to use a class variable, right?

It is a useful feature.

Sometimes per instance code needs to read or write per class data.

The most simple example is probably the well known constants:

private static final int N = 10;

Arne
 
C

Chris Uppal

Ravi said:
But a non static method is basically doing an instance service. Hence how
come instance service be allowed to manipulate a class variable ( or
static variable ) ? Surely C++ throws an exception, and is that not a
drawback in Java language syntax?

Unlike (it seems) the other people who have replied, I share your unease at
this arrangement -- it is simply unclean, and (IMO) reflects the lack of
understanding of good language design, and particularly of OO programming,
which gave rise to Java.

In this case, I have come to believe that the Java designers' idea of "static"
was that static members are somehow /shared/ between all the instances, rather
than belonging to a "something" that is separate from them. Of course, since
such members are not tied to any one instance, it might make sense to allow
people to use them without having /any/ instance (which conflicts with the idea
that they are shared, but there you go...). Since that is, in fact, a
practical necessity, there is a syntax/semantics for refering to static members
via the owning class's name.

Thus we end up with a muddle.

Most Java programmers agree that it is better to pretend that the sharing idea
never happened (though few of them would put it in those words ;-) Never use
an instance to access a static member. And only use static members unqualified
by the class name in contexts where you can understand the member name as being
"in scope".

-- chris
 
T

Tor Iver Wilhelmsen

Chris Uppal said:
Unlike (it seems) the other people who have replied, I share your unease at
this arrangement -- it is simply unclean, and (IMO) reflects the lack of
understanding of good language design, and particularly of OO programming,
which gave rise to Java.

Still, it's a preference; your unease seems to be shared with enough
developers that Eclipse has a setting for flagging instance access to
static members as a warning or error.

But if you think of namespace isolation and accessibility modifiers,
it makes sense because static members are "higher" than the instances,
like a virtual version of

private int someMethod();
{ // Outer namespace delimiter - think class
int it = 21;
{ // Inner namespace delimiter - think instance
String veryLocal = "This is very local";
// We can use "it" here because it's from a higher namespace
it = it * multiplier;
// Member fields are visible even if declared after this method
}
// Here, "veryLocal" is unavailable, "it" is the same as inside
// inner namespace
return it;
}
// A "real" instance field, visible to all instance methods of the class
// wherever they are declared.
int multiplier = 2;


In many ways this goes into the same camp as "why should a private
instance member be accessible from a different object?" i.e. language
design decisions that more than zero developers disagree with. :)

Then again, evey language should have Lisp/Scheme's "let" to localize
variables across calling scopes... but it would be a headache to
implement in Java.
 
?

=?ISO-8859-1?Q?Arne_Vajh=F8j?=

Tor said:
Still, it's a preference; your unease seems to be shared with enough
developers that Eclipse has a setting for flagging instance access to
static members as a warning or error.

Just to be absolutely clear.

Eclipse gives a warning on object.staticmember but
not on class.staticmember.

Which makes sense because the first one indicates
that one did not note that it was static.

But the second one is the one being discussed here.

Arne
 
T

Tor Iver Wilhelmsen

Arne Vajhøj said:
But the second one is the one being discussed here.

Then it's even more strange: The classes are globally (within a
classloader) accessible identifiers. The two real differences between
instance and static in Java is that instance methods are virtual, and
that instance references - methods or fields alike - need an object
reference on the stack.

Then the question becomes why an instance should be able to read a
static field (which is very useful for constants) but not write to it
(which appears to be what the OP reacts to). Java does not have access
modifiers for that, but there are two solutions:

1) Place the "guarded" static content in a different class.

// Package needs to be sealed in the jar so the library user
// cannot add to it.
package my.special.component;

public class MyStaticContent {

// The guarded data
private static int someValue = 42;

// No instances
private MyStaticContent() { }

// Public read method
public static int getSomeValue() {
return someValue;
}

// Mutating method is only visible to package.
static void setSomeValue(int value) {
someValue = value;
}

}

The problem is that the user conceivably could add a class in that
package anyway and add it to the library jar. Unless it was signed, in
which case that would fail to work.

It all depends on how important it is to not be able to mutate it
outside of static methods.

A better approach is

2) Use only instances and no static data. Manage all objects in a
container - like Spring. For the data that used to be static, use a
factory that produces one singleton object that is assigned to all
the objects that need the data it contains.
 
C

Chris Uppal

Tor Iver Wilhelmsen wrote:

[me:]
Still, it's a preference; your unease seems to be shared with enough
developers that Eclipse has a setting for flagging instance access to
static members as a warning or error.

I don't know if this is worthwhile, but just for the record -- the "unease" I
was speaking of was allowing instances direct access to class-side members (and
vice versa if it comes to that) which is not what the Eclipse warning is about
(unless you are thinking of a different setting from me).

In many ways this goes into the same camp as "why should a private
instance member be accessible from a different object?" i.e. language
design decisions that more than zero developers disagree with. :)

;-)

-- chris
 

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
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top