Example where static variables are unavoidable... does it exist?

T

TGOS

If I'd design a new language tomorrow (OO of course) and I'd
leave out static variables, do you think it would be fatal?

Can anyone provide me an example, where a certain problem
can't be solved without the existence of static variables in
Java? I challange you and claim "No such example exists".
Prove me wrong ;-)

The prototype example for static variable is "Count the
number of instances of a class". Well, I can do this without
static variables (and I will even write my code as very
clean OO):


class InstanceCounter {
private int instances;

public InstanceCounter() {
instances = 0;
}

public void addInstance() { instances++; }
public void removeInstance() { instances--; }

public int getNumberOfInstances() { return instances; }
}

class Foo {
private InstanceCounter ic;

public Foo(InstanceCounter ic) {
this.ic = ic;
ic.addInstance();
}

public void finalize() {
ic.removeInstance();
}
}


public class StaticTest {

public static void main(String[] args) {
InstanceCounter ic = new InstanceCounter();
Foo f1 = new Foo(ic);
Foo f2 = new Foo(ic);
Foo f3 = new Foo(ic);

System.out.println("There are " +
ic.getNumberOfInstances() +
" instances of Foo.");

f1 = null;
System.gc();


System.out.println("There are " +
ic.getNumberOfInstances() +
" instances of Foo.");
}
}

Output:

There are 3 instances of Foo.
There are 2 instances of Foo.

Instance counter, you see :)
 
S

Suresh

How would you implement the following functions:

System.setErr(...)
Runtime.getRuntime()
etc ...
 
T

TGOS

How would you implement the following functions:
System.setErr(...)
Runtime.getRuntime()
etc ...

These are static methods, I was talking about static
variables.
Not quite the same. Let's first focus on this...


But static methods are not necessary either.
I would implement them as one of the following ways:

1.) You receive a reference to a main object in the main
method (which wouldn't be static either):

public void main(String[] args, java.lang.VirtualMachine vm)
{
vm.getSystem().setErr(...);
// vm.getSystem() returns an instance of
java.lang.System
// which is a singleton: There is only one instance
// and new doesn't work, private constructor
Runtime r = vm.getRuntime();
// Runtime is also a singleton

2.) I extend Object.

java.lang.Object gets a method getVirtualMachine(), so every
object can always call this method to receive a reference to
it if necessary. Despite that, everything like above.


3.) I hard code singleton into the VM:

Singleton s1 = new Singleton();
Singleton s2 = new Singleton();

and

s1 == s2

will be true. Singleton is defined as

public singleton class Singleton {}

The first time someone calls new, a new instance is created
and the constructor is called. The second, third, fourth,
... time just a reference to the existing object is
returned.

That way, your examples would work as:

new System().setErr(...)
new Runtime().getRuntime()

As the VM would set up System and Runtime already before it
even enters the main method, so references to the already
existing objects are returned instead of the creation of new
ones. That means:

System sys = new System();
sys.setErr(...);
sys.setErr(...);

is exactly equivalent to

new System().setErr(...);
new System().setErr(...);

Just one limitation had to apply: Singletons only have one
constructor and that constructor mustn't have any
parameters. Otherwise

new System("test");

and

new System(2);

can never return the same singleton, as the initialization
of the object would be somehow different (otherwise why are
there two constructors?)


--
TGOS

I am working with Windows 2K & XP, MacOS X 10.2 and
Linux 2.4 on a daily basis, and let me assure you, they
all suck! There is really no need to argue about
which one sucks most, they all suck equally.
 
C

Chris Riesbeck

TGOS said:
The prototype example for static variable is "Count the
number of instances of a class". Well, I can do this without
static variables (and I will even write my code as very
clean OO):


class InstanceCounter {
...
}

class Foo {
private InstanceCounter ic;

public Foo(InstanceCounter ic) {
...
}
}


public class StaticTest {

public static void main(String[] args) {
InstanceCounter ic = new InstanceCounter();
Foo f1 = new Foo(ic);
Foo f2 = new Foo(ic);
Foo f3 = new Foo(ic);
Instance counter, you see :)

But it requires the client code to create it, and
Foo to take it as an argument. The responsibilities
are scattered across classes. A pain to maintain.
It's OO but not *clean* OO.
 
R

Roedy Green

Can anyone provide me an example, where a certain problem
can't be solved without the existence of static variables in
Java? I challange you and claim "No such example exists".
Prove me wrong ;-)

Why do you want to get rid of them?

It becomes pretty inefficient to initialise a table from a file every
time you instantiate an object rather than just the first time you use
a class.

I guess what you are suggesting in you would explicitly instantiate
class objects then data objects.

What is your mechanism that data objects would find their
corresponding class objects? Would this be automatic, or would the
application have to juggle pointers and pass them as a parameters?

As you add a few conveniences, you would likely find yourself right
back at a syntax that looks just like statics.
 
T

TGOS

Why do you want to get rid of them?

I think they violate the OO concept.
Objects are objects, they can store values inside and you can send
message to them (call methods) and retrieve replies from them. But
classes are just construction plans of objects.

It's like houses and the plan how to build them. I can have a plan how
to build a house and can make hundreds of houses according to that plan.
Houses are objects, I can interact with them (open/close doors and
windows, walk in and walk out), but I can't interact with a building
plan! It's piece of paper with some drawing on it and nothing more.

Having a class, that can hold data or offers methods doesn't fit into
the OO concept of just having objects that interact with each other as
classes are no objects (well, they are, but not in the sense of OO
programming).
It becomes pretty inefficient to initialise a table from a file every
time you instantiate an object rather than just the first time you use
a class.

Table tab = new Table("/dir/somefile");
MyOjbect o1 = new MyObject(tab);
MyOjbect o2 = new MyObject(tab);
MyOjbect o3 = new MyObject(tab);

I created three objects, but only once initialized the table. The table
just has to be an object of its own, what is a much better OO concept,
than storing the table internally in some data structure not accessible
to the programmer.
What is your mechanism that data objects would find their
corresponding class objects?

Sorry, but already the term "data object" sounds foreign to me. An
object is an object, there are not different *groups* of objects.

What is a data object and why would it have to find any class object?
Would this be automatic, or would the
application have to juggle pointers and pass them as a parameters?

Can't answer before you answer my question of above :)
Code examples are helpul...
 
R

Roedy Green

I created three objects, but only once initialized the table. The table
just has to be an object of its own, what is a much better OO concept,
than storing the table internally in some data structure not accessible
to the programmer.

But that breaks encapsulation to require clients to pass in the
handles to all the tables an object needs. Objects should be able to
arrange this behind the scenes for themselves.
 
R

Roedy Green

Sorry, but already the term "data object" sounds foreign to me. An
object is an object, there are not different *groups* of objects.

In Java it all gets muddled together:

1. class methods. (static)
2. per class variables (static)
3. instance methods
4. instance objects


Behind the scenes is a class object holding the static variables and
pointers to all the methods, instance and static.

Each object has a pointer to its corresponding class object.

What I meant by "data object" was the instance object -- the thing you
create with new.

What I am asking is where would you put the per class variables and
how would an object find them?
 
W

Wojtek

If I'd design a new language tomorrow (OO of course) and I'd
leave out static variables, do you think it would be fatal?

Can anyone provide me an example, where a certain problem
can't be solved without the existence of static variables in
Java? I challange you and claim "No such example exists".
Prove me wrong ;-)

The best example I can think of is elimination of "magic numbers".

For instance in the Calendar class there are a number of static
variables which hold values for parameters, such as Calendar.MINUTE

I also use them for specifying HTML imput names:

<input type="text" name="<%= HtmlNames.PASSWORD %>"
where:

public class HtmlNames
{
public static final String PASSWORD = "pass";
}

Which nicely coordinates the JSP with the servlet. Moreover since all
the HTML names are defined in one place, there is less likelyhood of
name collision.
 
T

TGOS

But it requires the client code to create it,

Yes... and your point is?

java.util.StringTokenizer also requires the client code to create the
String, it won't create a String on it's own. If I want to tokenize a
String, I first need to create the String somehow. And if I want to know
the number of instances, I first have to create an instance counter.
Where's the problem?
and Foo to take it as an argument.

Yes... and your point is?

Despite that, Foo can have a constructor that does not require an
InstanceCounter object, then it will simply not count instances.
The responsibilities are scattered across classes.

What responsibilities are you talking about?
A pain to maintain.

I don't see that pain.
 
T

TGOS

But that breaks encapsulation to require clients to pass in the
handles to all the tables an object needs.

No, not to all. Only to those shared by different instances of the
object. And it does not destroy data protection, because MyObject may
actually have a constructor like that

public MyObject(Table t) {
internalTable = t.clone();
}

And t.clone() may work the following way: It will do nothing more than
creating a new Table, but this new one uses the same data structures
than t and t notes internally that it has been cloned. If now the main
program tries to modify the Table (after it has been passed as argument
to multiple MyObjects), t will copy it's internal data structures and
then only modify the copy. The other structures shared between the
clones will stay unmodified.
Objects should be able to
arrange this behind the scenes for themselves.

Maybe, but that's the point. "Objects" should...
As I wrote before:

It's like houses and the plan how to build them.

Objects should, not classes. But static stuff is class stuff. It belongs
to a "class" and that doesn't seem to fit concept. A class can't own
anything or accept any messages, it's no object. Only objects can own
data or receive messages.
 
T

TGOS

What I meant by "data object" was the instance object -- the thing you
create with new.
Okay...

What I am asking is where would you put the per class variables and
how would an object find them?

There wouldn't be any per class variables (because a class can't have
variables, it's building plan, not a house), hence an object couldn't
find them and wouldn't even try to find them.


What I'm looking for is someone providing me with a problem, that I
can't solve without the usage of a static variable in Java, but that he
can solve using a static variable. If no such example exists, static
variables (useful or not) are no necessity, as they don't allow
programmers to do something that wouldn't also work without static
variables.
 
R

rkm

TGOS said:
Can anyone provide me an example, where a certain problem
can't be solved without the existence of static variables in
Java? I challange you and claim "No such example exists".
Prove me wrong ;-)

I think you can always provide an elaborate enough mechanism
to simulate anything a static variable can "do". So the
question probably should be would the mechanism be so
elaborate as to make everyone wish they had good ol statics?

Here's a use of static variables I see frequently, haven't
thought about how to do it your way. Indentation indicates
inheritance from the less indented class.

topClass
midClass1
static ExpensiveResource myRsrc1; // not a singleton
botClass1; // shares use of static myRsrc1
botClass2; // shares use of static myRsrc1
midClass2
static ExpensiveResource myRsrc2; // not a singleton
botClass3; // shares use of static myRsrc2
botClass4; // shares use of static myRsrc2

Sure, you could pass the ExpensiveResource into the
constructors for the bottom classes so they have their own
reference, but then you have to track and pass the correct
one all over the place to make sure anyone instantiating one
of the bottom classes has the right ExpensiveResource
available to pass in. As I said already, you can certainly
implement some mechanism to accomplish that, like a
depository where all shared objects can be stored to and
fetched from as needed, but the static mechanism is far
easier to deal with, I would think.

Rick
 
T

TGOS

The best example I can think of is elimination of "magic numbers".

Sounds interesting, tell me more ... :)
For instance in the Calendar class there are a number of static
variables which hold values for parameters, such as Calendar.MINUTE

But these are actually constants. Java lacks the principle of real
constants, instead "public static final" variables are used. Do
constants have to be static... wouldn't all variables point to the same
object anyway since they are constant? Well, in Java of course not.

But still, the following works:

String s1 = "test";
String s2 = "test";

s1 == s2

Because they both really show to the same object, as the compiler will
only create one constant string "test" and both times use a reference to
it. However, this will only work as long as both strings are within the
same class (and the value is constant, because String values are
constant). Between different classes, you have to use equals() of
course.
 
T

TGOS

topClass
midClass1
static ExpensiveResource myRsrc1; // not a singleton
botClass1; // shares use of static myRsrc1
botClass2; // shares use of static myRsrc1
midClass2
static ExpensiveResource myRsrc2; // not a singleton
botClass3; // shares use of static myRsrc2
botClass4; // shares use of static myRsrc2

Yes, someone else mentioned that example before.
And like you said, you can code around it.
You could pass in the resource or use a depository (an object pool
available to all objects to easily share resources).

How are these cases handles in Smalltalk? There are no class variables
in Smalltalk, right?
 
R

Roedy Green

If I'd design a new language tomorrow (OO of course) and I'd
leave out static variables, do you think it would be fatal?

I tend to look at this proposal as similar to "If all the chairs in
the world were abducted by aliens, would we survive?"

I don't think you have convinced anyone there would be any benefit to
doing away with statics.
 
W

Wojtek

Sounds interesting, tell me more ... :)


But these are actually constants. Java lacks the principle of real
constants, instead "public static final" variables are used. Do
constants have to be static... wouldn't all variables point to the same
object anyway since they are constant? Well, in Java of course not.

So you think that:
- in C and C++
#define HTML_NAME_PASSWORD "pass"
- in Visual Basic
Public Const HTML_NAME_PASSWORD as String = "pass"
- in PHP
define("HTML_NAME_PASSWORD","pass");

is better than:
public class HtmlNames
{
public static final String PASSWORD = "pass";
}

If so, why? I think the Java way is better. Among other things, it
encapsulates the "constant" within its context, whereas the other
define statements must have the context as part of the name. Also they
must be global variables (which breaks OO).
But still, the following works:

String s1 = "test";
String s2 = "test";

s1 == s2

Because they both really show to the same object, as the compiler will
only create one constant string "test" and both times use a reference to
it. However, this will only work as long as both strings are within the
same class (and the value is constant, because String values are
constant). Between different classes, you have to use equals() of
course.

Actually that is up to the compiler writer. You cannot depend on the
compiler only creating one "test" within a class, then pointing all
references to it.
 
T

Timo Kinnunen

TGOS said:
No, not to all. Only to those shared by different instances of the
object. And it does not destroy data protection, because MyObject
may actually have a constructor like that

public MyObject(Table t) {
internalTable = t.clone();
}

And t.clone() may work the following way: It will do nothing more
than creating a new Table, but this new one uses the same data
structures than t and t notes internally that it has been cloned.
If now the main program tries to modify the Table (after it has
been passed as argument to multiple MyObjects), t will copy it's
internal data structures and then only modify the copy. The other
structures shared between the clones will stay unmodified.

Then, I can break that by doing:

Table table = new Table();
Table tableClone = table.clone();
MyObject o1 = new MyObject(table);
MyObject o2 = new MyObject(table);

tableClone.modify(...);

This is doubtly insidious because it looks like I'm legitimaly modifying
a copy. To fix that problem, the clone method's name could be changed to
internalHelperMethod1ForMyObjectUseONLY, but then the break in
encapsulation would be apparant.

Making clone package-private would fix the problem for other packages
and a friend declaration would fix it alltogether. I don't know if you
view those as breaking encapsulation, but they weren't used in your
original example.
 
T

Timo Kinnunen

TGOS said:
If I'd design a new language tomorrow (OO of course) and I'd
leave out static variables, do you think it would be fatal?

Can anyone provide me an example, where a certain problem
can't be solved without the existence of static variables in
Java? I challange you and claim "No such example exists".
Prove me wrong ;-)

I can't, because static variables can always be converted into another
class, whose instance is passed to newly created objects.

You can pretend that code like this:

public class MyObject {
private static int count = 0;

public MyObject() { count++; }
public int getCount() { return count; }
}

is converted internally into this:

public class MyObject {
static class MyObject$Static {
int count = 0;
}

// has to be an array in case this class is a super-class.
private MyObject$Static[] static;

public MyObject(VirtualMachine vm) {
static = vm.getStatic(this.getClass()); // creates if not found
static[0].count++;
}
public int getCount() { return static[0].count; }
}

So, it is already being done, if you convince yourself that it is :)
 
T

TGOS

So you think that:
- in C and C++
#define HTML_NAME_PASSWORD "pass"

This is not a constant.
It is a macro for the pre-compiler.
Before the compiler actually ever sees the source code, all occurances
of HTML_NAME_PASSWORD are replaced by "pass".

A constant in C and C++ would be:

const int MAX_LENGTH = 255;
is better than:
public class HtmlNames
{
public static final String PASSWORD = "pass";
}

If so, why?

Because I dislike public variables.
Going by strict OO principles, all variables of an object are supposed
to be private (or protected) IMHO.

Sure, you could then do something like

public class HtmlNames {
private final String PASSWORD = "pass";
String getPASSWORD() { return PASSWORD; }
}

and a clever JIT compiler would then replace

String s = xyz.getPASSWORD();

with

String s = ##Reference to private final String PASSWORD##

so no method call ever takes place... but I'm not sure if I'd like that
any more.
Actually that is up to the compiler writer. You cannot depend on the
compiler only creating one "test" within a class, then pointing all
references to it.

No, you can't, but a compiler doing it not that way would always create
bigger, less optimized class files than Sun's compiler and could not
compete. I think all compilers detect String constants, also those of
other languages.
 

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

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top