Java trick

R

Razvan

Hi !




public class CDummy
{
static int toto = 7;

CDummy getDummy() {
return null; // pay attention here !
}

public static void main(String args[])
{
System.out.println("CDummy.");

CDummy dmy = new CDummy();
System.out.println(dmy.getDummy().toto);
}
}



Well... can you guess the output of the above code ? (try not to run the code)

I have my own explanation but I don't want to spoil your fun:))



Regards,
Razvan
 
J

Joona I Palaste

Razvan said:
public class CDummy
{
static int toto = 7;
CDummy getDummy() {
return null; // pay attention here !
}
public static void main(String args[])
{
System.out.println("CDummy.");
CDummy dmy = new CDummy();
System.out.println(dmy.getDummy().toto);
}
}
Well... can you guess the output of the above code ? (try not to run the code)
I have my own explanation but I don't want to spoil your fun:))

Yes, we're all aware of this. IMHO it's a nasty kludge that only serves
to confuse people. The people who designed Java and wrote the JLS must
have been smoking some pretty heavy stuff when they allowed this.
 
J

Jacob

Razvan said:
System.out.println(dmy.getDummy().toto);

You're accessing a static variable so which instance
you you use as reference doesn't matter, only its class
does. Makes sense to me.

For code readbility: Always refer to static elements
(variable or methods) by class, not instance:

System.out.println (CDummy.toto);
 
A

Adam

You are not referencing 'this' which is null,
so it works fine, even if looks ugly.

In C++ this is even worse:

class CSomeClass
{
public:
void foo(){ printf("My 'this' can be null, I dont care!!!"); }
}

.....
CSomeClass* pointer;
pointer->foo();
.....

This will compile and run correctly,
even though foo() is not static.

Adam
 
A

andreas

Yes, we're all aware of this. IMHO it's a nasty kludge that only serves
to confuse people. The people who designed Java and wrote the JLS must
have been smoking some pretty heavy stuff when they allowed this.

IMHO this behaviour is very consistent.
since a object can be null at any time and the method returns
an object of type CDummy the returned value is

null of type CDummy. therefore the static variable is accessable.

andreas
 
C

Chris Smith

andreas said:
IMHO this behaviour is very consistent.
since a object can be null at any time and the method returns
an object of type CDummy the returned value is

null of type CDummy. therefore the static variable is accessable.

I'm trying to understand what you mean, and I'm having trouble. My
trouble starts when you say "a object can be null at any time". In
fact, an object can't be null, ever. In fact, 'null' means that no
object exists. It's a placeholder value for a reference that does not
point to an object.

The ugliness of this example isn't that the reference is null when the
variable is accessed; it's that the static variable can be accessed
through a reference in the first place. Since there's no clear meaning
to using a static variable through a reference at all, it's pointless to
talk about whether or not it's consistent to allow access through a null
reference. At that point, you've just gotta abandon "consistent" and
read the JLS with a fine-toothed comb.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
B

Brian

Chris Smith said:
The ugliness of this example isn't that the reference is null when the
variable is accessed; it's that the static variable can be accessed
through a reference in the first place. Since there's no clear meaning
to using a static variable through a reference at all, it's pointless to
talk about whether or not it's consistent to allow access through a null
reference. At that point, you've just gotta abandon "consistent" and
read the JLS with a fine-toothed comb.

[novice here]

So using static members and methods via references /could/ be disallowed
with no ill effects?
 
J

Joona I Palaste

[novice here]
So using static members and methods via references /could/ be disallowed
with no ill effects?

Yes. It's just syntactic sugar for accessing them via class names, as
only the type of the reference matters, not its value.

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"And according to Occam's Toothbrush, we only need to optimise the most frequent
instructions."
- Teemu Kerola
 
T

Thomas G. Marshall

andreas coughed up:
IMHO this behaviour is very consistent.
since a object can be null at any time and the method returns
an object of type CDummy the returned value is

null of type CDummy.
*Almost*.


therefore the static variable is accessable.

andreas


I agree in that I think that the static should be honored, and the code
should work.

But you've got the explanation a little wrong.

"null" is /always/ of the /Null Type/. It has its own type, always. I'm
not a fan of that particularly, but it's the way it is in the jls.

The reason it works is that a variable to a class object of any value can
still yield access to a static. It's makes sense to me, since the static
variable /belongs/ to the class, regardless of what the object reference is,
or isn't.
 
T

Thomas G. Marshall

Joona I Palaste coughed up:
[novice here]
So using static members and methods via references /could/ be
disallowed with no ill effects?

Yes. It's just syntactic sugar for accessing them via class names, as
only the type of the reference matters, not its value.

Given that you can do this, again I have no issue with the result. But if
the question ever became "should you be allowed to grab a class static from
a reference", then I'd really have to answer "no."

AFAIAC, it seems to violate something fundamental in OO land....
 
M

Michael Borgwardt

Thomas said:
The reason it works is that a variable to a class object of any value can
still yield access to a static.

Actually, there is no object involved at any point. The *compiler* directly
inserts a reference to the class for which the variable is declared, so
it might work differently than expected if inheritance is involved.

ClassA reference = new SubClassOfClassA();
System.out.println(reference.staticVariable);

is equivalent to

System.out.println(ClassA.staticVariable);

NOT to

System.out.println(SubClassOfClassA.staticVariable);
 
T

Tor Iver Wilhelmsen

Adam said:
This will compile and run correctly,
even though foo() is not static.

IIRC, it's because the member method foo() is "synthesized" into the C
method

CSomeClass_foo(CsomeClass* this) {

}

and your code doesn't use "this" for anything.

Methods in Java are "real" member methods.

To the OP: Whether you get the static member's value or a
NullPointerException depends on which runtime you use: There was a
change-note for one version (I seem to recall) that spoke of a change
regarding whether your code should give a NPE at runtime or not.
 
M

Mike Schilling

Michael Borgwardt said:
Actually, there is no object involved at any point. The *compiler*
directly
inserts a reference to the class for which the variable is declared, so
it might work differently than expected if inheritance is involved.

ClassA reference = new SubClassOfClassA();
System.out.println(reference.staticVariable);

is equivalent to

System.out.println(ClassA.staticVariable);

NOT to

System.out.println(SubClassOfClassA.staticVariable);

Good point. This is the compiler doing what you (probably) meant rather
than what you said.

Note that C# forbids this. It will only accept

ClassA.staticVariable

and

ClassA.staticMethod()

Attempting to reference static members via an instance results in a
compilation error. Since some number of people will be surpised when, as
Michael points out, the reference to the static is not virtual, I think C#
got this right.
 
M

Malcolm Dew-Jones

Thomas G. Marshall ([email protected]) wrote:
: Joona I Palaste coughed up:
: > Brian <[email protected]> scribbled the following:
: >>> The ugliness of this example isn't that the reference is null when
: >>> the variable is accessed; it's that the static variable can be
: >>> accessed through a reference in the first place. Since there's no
: >>> clear meaning to using a static variable through a reference at
: >>> all, it's pointless to talk about whether or not it's consistent to
: >>> allow access through a null reference. At that point, you've just
: >>> gotta abandon "consistent" and read the JLS with a fine-toothed
: >>> comb.
: >
: >> [novice here]
: >
: >> So using static members and methods via references /could/ be
: >> disallowed with no ill effects?
: >
: > Yes. It's just syntactic sugar for accessing them via class names, as
: > only the type of the reference matters, not its value.

: Given that you can do this, again I have no issue with the result. But if
: the question ever became "should you be allowed to grab a class static from
: a reference", then I'd really have to answer "no."

On the other hand, a class should be able to hide implemetation details
about itself. Allowing an object to access a static item in its class
allows the implementation to be changed. In particular, something that is
initially implemented as a class constant might later become something
that varies based on other factors within each object. E.g. sales tax on
every item might be a constant when the code is written, but the next year
this might be changed to vary based on the cost of an item. The tax
"constant" is no longer a constant, but any code that said "item.tax_rate"
would still work.

Of course you may wish to have implemeted a getTaxRate method in the first
place, but that's a different issue.
 
C

Chris Smith

Malcolm said:
On the other hand, a class should be able to hide implemetation details
about itself. Allowing an object to access a static item in its class
allows the implementation to be changed. In particular, something that is
initially implemented as a class constant might later become something
that varies based on other factors within each object.

This is really a no-starter in terms of a reason for allowing a
confusing syntax for accessing static variables. Whether a property is
static or not isn't an implementation detail, and you're going to run
into all kinds of problems if you treat it as one.

If you need to change a static constant to an instance field in a way
that you didn't anticipate, there's a LOT of vetting of existing client
code that needs to happen anyway, and the compile errors would help you
considerably. Of course, if you did anticipate the change, then the
value wouldn't be a static field in the first place.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
T

Thomas G. Marshall

Michael Borgwardt coughed up:
Actually, there is no object involved at any point. The *compiler*

{shrug} The *compiler* does everything.

directly inserts a reference to the class for which the variable is
declared, so
it might work differently than expected if inheritance is involved.

ClassA reference = new SubClassOfClassA();
System.out.println(reference.staticVariable);

is equivalent to

System.out.println(ClassA.staticVariable);

NOT to

System.out.println(SubClassOfClassA.staticVariable);


You're right. What I really should have said was a "variable of reference
of any value", not object.

Basically, given the declaration & definition:

{Type} {Variable Name} = {reference};

*Regardless* of the value of {reference},

{reference}.{static id}

yields the same thing as

{Type}.{static id}

Which is something I've always thought sloppy about Java.
 
T

Thomas G. Marshall

Tor Iver Wilhelmsen coughed up:
IIRC, it's because the member method foo() is "synthesized" into the C
method

CSomeClass_foo(CsomeClass* this) {

}

and your code doesn't use "this" for anything.

Methods in Java are "real" member methods.

To the OP: Whether you get the static member's value or a
NullPointerException depends on which runtime you use: There was a
change-note for one version (I seem to recall) that spoke of a change
regarding whether your code should give a NPE at runtime or not.

HUH? Which?
 
M

Michael Borgwardt

Thomas said:
Basically, given the declaration & definition:

{Type} {Variable Name} = {reference};

*Regardless* of the value of {reference},

{reference}.{static id}

yields the same thing as

{Type}.{static id}

Which is something I've always thought sloppy about Java.

I (and most knowledgeable people I know) think that static members
should be accessible only through the class name, not through
a reference.
 
K

Kevin McMurtrie

Hi !




public class CDummy
{
static int toto = 7;

CDummy getDummy() {
return null; // pay attention here !
}

public static void main(String args[])
{
System.out.println("CDummy.");

CDummy dmy = new CDummy();
System.out.println(dmy.getDummy().toto);
}
}



Well... can you guess the output of the above code ? (try not to run the
code)

I have my own explanation but I don't want to spoil your fun:))



Regards,
Razvan

Some compilers can give you a warning that you're not using the instance
variable because the method/field is static. Eclipse has that option.
 
L

Lee Fesperman

Thomas said:
Michael Borgwardt coughed up:
Actually, there is no object involved at any point. The *compiler*

[snip]

You're right. What I really should have said was a "variable of reference
of any value", not object.

Basically, given the declaration & definition:

{Type} {Variable Name} = {reference};

*Regardless* of the value of {reference},

{reference}.{static id}

yields the same thing as

{Type}.{static id}

It's simply a reference, you don't need a variable at all. It is any expression
producing a reference. It could be a method returning a reference or even:

((Type) null).{static id}

The static can be a field or a method.
 

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
474,262
Messages
2,571,059
Members
48,769
Latest member
Clifft

Latest Threads

Top