Java trick

B

Babu Kalakrishnan

Tor said:
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.

I'm curious about this too. I thought the compiler was the one which
would automatically convert the instance based reference to a class
reference. In which case how would the runtime know about the instance
at all ? (to check for null)

BK
 
T

Thomas G. Marshall

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

Yeah. Some compilers (like eclipse's) allow a setting to change the
compiler's reaction to that from silent, to warning, to error. At least
that's a start.
 
J

Joona I Palaste

I'm curious about this too. I thought the compiler was the one which
would automatically convert the instance based reference to a class
reference. In which case how would the runtime know about the instance
at all ? (to check for null)

Isn't the implementation even *required* by the JLS to ignore the value
of the reference (null, same class object, subclass object...)
completely and only use its type? In which case whatever gives a
NullPointerException when calling a static method through null doesn't
deserve to call itself Java.
 
T

Thomas G. Marshall

Lee Fesperman coughed up:
Thomas said:
Michael Borgwardt coughed up:
Thomas G. Marshall wrote:
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*

[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.


Your example is good, and it's one I've used before, except that your
explanation is missing how the thing is declared, which is why it isn't
about the reference.

The variable is declared with a type somewhere, or passed in as a formal
parameter of some type, etc. It is that type that determines the static
used, not the actual polymorphised object underneath.

As Michael Borgwardt perfectly pointed out, it is not the reference (object)
per se:

Michael Borgwardt:
"ClassA reference = new SubClassOfClassA();
System.out.println(reference.staticVariable);

is equivalent to

System.out.println(ClassA.staticVariable);

NOT to

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

Because as he puts it, it's the compiler that did the work.
 
T

Thomas G. Marshall

Joona I Palaste coughed up:
Isn't the implementation even *required* by the JLS to ignore the
value of the reference (null, same class object, subclass object...)
completely and only use its type?

I thought so.

But a source of arguments seem to arise (that I've seen) as to what "type"
really means when you are referring to polymorphized types. I'm accepting
of either way:

In this:

Super sub = new Sub();

Is the terminology we use for the "type" of the reference held in sub
referring to "Super" or "Sub"? The rule as you (and others) have stated it
says that the reference object just doesn't matter and that the static
belongs to Super. Which is what is meant by the reference's type in that
case.

But arguments seem to spring up when people use the term Type to mean the
type of the polymorphized object. Beats me. {shrug with palms up} I
personally accept both ways.
 
J

Joona I Palaste

Thomas G. Marshall said:
Joona I Palaste coughed up:
I thought so.
But a source of arguments seem to arise (that I've seen) as to what "type"
really means when you are referring to polymorphized types. I'm accepting
of either way:
Super sub = new Sub();
Is the terminology we use for the "type" of the reference held in sub
referring to "Super" or "Sub"? The rule as you (and others) have stated it
says that the reference object just doesn't matter and that the static
belongs to Super. Which is what is meant by the reference's type in that
case.
But arguments seem to spring up when people use the term Type to mean the
type of the polymorphized object. Beats me. {shrug with palms up} I
personally accept both ways.

Because of this I have a Java-specific terminology that makes things
clear. The fundamental rule is:
Objects have class. References have type.
In the above, the type of sub is Super. The class of the object that sub
refers to is Sub.
Types and classes have an "is-assignable-to" relationship. A class
is-assignable-to a type that is the type of the same class, a type of
any of its superclasses, or a type of any interface it implements.
 
T

Thomas G. Marshall

Joona I Palaste coughed up:
Thomas G. Marshall








Because of this I have a Java-specific terminology that makes things
clear. The fundamental rule is:
Objects have class. References have type.
In the above, the type of sub is Super. The class of the object that
sub
refers to is Sub.
Types and classes have an "is-assignable-to" relationship. A class
is-assignable-to a type that is the type of the same class, a type of
any of its superclasses, or a type of any interface it implements.

Why is that Java-specific?

For yucks, I posted my terminology question on c.o, to see how badly the
purists yell at me :)
 
J

Joona I Palaste

Thomas G. Marshall said:
Joona I Palaste coughed up:
Why is that Java-specific?

It's not, actually. It's specific to any language with the same
polymorphic type system as Java. But I couldn't come up with any others
having the exact same system.
 
G

Gary Labowitz

Thomas G. Marshall said:
Michael Borgwardt coughed up:

{shrug} The *compiler* does everything.




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.

I sorta object to your using {Type}. etc. The way I teach it would seem to
eliminate the confusion: Ahem....

Data is referred to based on the class of the reference variable.
Methods are referred to based on the class of the object.

This means that if a reference variable is declared as class Dummy, then
regardless of whether it addresses an actual object or not (i.e. is Null)
any data referred to with that reference will be located with reference to
the Class, in this case Dummy. So whether it is null, addresses a valid
Dummy object, or a derived class of Dummy it will refer to the static data
in Dummy, because it is a Dummy reference.

Methods work differently, using dynamic dispatch to find the code to be
executed -- based on the object that is being referred to. So if the
reference variable contains null you get a null pointer exception. If the
reference variable refers to an existing object, that object's loaded
methods are searched, proceeding up the inheritance chain if necessary to
find the code to execute. Hence, polymorphism. Even if the reference is
declared as a Base class, it still uses the object's methods.

[This phrasing eliminates my having to go into static/dynamic resolution of
identifiers by the compile process. They are, after all, beginners.]

Make corrections as appropriate.....
 
G

Gary Labowitz

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

Yes, yes, yes, and yes. Please cast my vote for this restriction at the next
committee meeting.
 
G

Gary Labowitz

Gary Labowitz said:
"Thomas G. Marshall"
wrote in message news:dbO2d.593$kn2.486@trndny07...

I sorta object to your using {Type}. etc. The way I teach it would seem to
eliminate the confusion: Ahem....

Data is referred to based on the class of the reference variable.
Methods are referred to based on the class of the object.

This means that if a reference variable is declared as class Dummy, then
regardless of whether it addresses an actual object or not (i.e. is Null)
any data referred to with that reference will be located with reference to
the Class, in this case Dummy. So whether it is null, addresses a valid
Dummy object, or a derived class of Dummy it will refer to the static data
in Dummy, because it is a Dummy reference.

Methods work differently, using dynamic dispatch to find the code to be
executed -- based on the object that is being referred to. So if the

First correction: after "referred to." insert "except if the method is
static." etc.
reference variable contains null you get a null pointer exception. If the
reference variable refers to an existing object, that object's loaded
methods are searched, proceeding up the inheritance chain if necessary to
find the code to execute. Hence, polymorphism. Even if the reference is
declared as a Base class, it still uses the object's methods.

[This phrasing eliminates my having to go into static/dynamic resolution of
identifiers by the compile process. They are, after all, beginners.]

Make corrections as appropriate.....
 
J

Joona I Palaste

Yes, yes, yes, and yes. Please cast my vote for this restriction at the next
committee meeting.

Mine, too. Cast one for my sister and brother and my parents too. (They
don't know enough about programming to care. My sister's boyfriend
does.)

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"I said 'play as you've never played before', not 'play as IF you've never
played before'!"
- Andy Capp
 
T

Thomas G. Marshall

Gary Labowitz coughed up:
"Thomas G. Marshall"


I sorta object to your using {Type}. etc. The way I teach it would
seem to eliminate the confusion: Ahem....

Data is referred to based on the class of the reference variable.
Methods are referred to based on the class of the object.

No, you're wrong, and you've made it even more confusing.

1. Static data OR METHODS are referred to based upon the /declaration/ of
the Class (of the reference variable for example).

2. Non static data are ALSO referred to based upon the declaration of the
Class.

3. Non static methods are referred to based upon the type of the
polymorphized object underneath.

This is the run result:

$ run experiments.simple.StaticPolyAccess
Top static string
Top static method
Top non static string
Bottom nonstatic method

And this is the source:

<SOURCE>
package experiments.simple;

class Top
{
static String staticstring = "Top static string";
static void staticmethod() {System.out.println("Top static method");}
String nonstaticstring = "Top non static string";
void nonstaticmethod() {System.out.println("Top nonstatic method");}
}

class Bottom extends Top
{
static String staticstring = "Bottom static string";
static void staticmethod() {System.out.println("Bottom static method");}
String nonstaticstring = "Bottom non static string";
void nonstaticmethod() {System.out.println("Bottom nonstatic method");}
}

public class StaticPolyAccess
{
public static void main(String[] args)
{
Top bottom = new Bottom();
System.out.println(bottom.staticstring);
bottom.staticmethod();
System.out.println(bottom.nonstaticstring);
bottom.nonstaticmethod();
}
}
</SOURCE>


....[rip]...
Make corrections as appropriate.....

Done. :)
 
T

Thomas G. Marshall

Joona I Palaste coughed up:
Mine, too. Cast one for my sister and brother and my parents too.
(They don't know enough about programming to care. My sister's
boyfriend does.)

I'm fairly certain that my two golden retreivers agree with us as well.
Heck, I'll go ask...
 
L

Lee Fesperman

Thomas said:
Lee Fesperman coughed up:
Thomas said:
Michael Borgwardt coughed up:
Thomas G. Marshall wrote:
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*

[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.

Your example is good, and it's one I've used before, except that your
explanation is missing how the thing is declared, which is why it isn't
about the reference.

The variable is declared with a type somewhere, or passed in as a formal
parameter of some type, etc. It is that type that determines the static
used, not the actual polymorphised object underneath.

You completely missed my point. It is about the reference. A variable is not necessary.
There is no 'thing' declared. Try these:

new String().valueOf("*");

"".valueOf("*");

((String) null).valueOf("*");

String.valueOf("").valueOf("*");

There are no variables involved. These all use reference expressions. The compiler uses
the type of the reference expression to call the appropriate static method --
String.valueOf().
 
T

Thomas G. Marshall

Lee Fesperman coughed up:
Thomas said:
Lee Fesperman coughed up:
Thomas G. Marshall wrote:

Michael Borgwardt coughed up:
Thomas G. Marshall wrote:
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*

[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.

Your example is good, and it's one I've used before, except that your
explanation is missing how the thing is declared, which is why it
isn't about the reference.

The variable is declared with a type somewhere, or passed in as a
formal parameter of some type, etc. It is that type that determines
the static used, not the actual polymorphised object underneath.

You completely missed my point. It is about the reference. A variable
is not necessary. There is no 'thing' declared. Try these:

new String().valueOf("*");

"".valueOf("*");

((String) null).valueOf("*");

String.valueOf("").valueOf("*");

There are no variables involved. These all use reference expressions.
The compiler uses the type of the reference expression to call the
appropriate static method -- String.valueOf().

To me, when someone says "it's about the reference", they are in effect
saying that it's about the object that that references points to, since
that's what a reference does.

Given a reference to an object instance of the class Sub, you still do not
know what static method is going to be called when you see this:

sub.staticmethod()

It would be different if the variable had been declared as

Super sub = new Sub();

than if it were

Sub sub = new Sub();

So the reference is the same in both cases (a sub object), but it is the
class that it is declared as (or casted to as you point out) that matters.
The reference by itself isn't enough. The compiler looks to see which class
is used.
 
J

Joona I Palaste

Thomas G. Marshall said:
Lee Fesperman coughed up:
To me, when someone says "it's about the reference", they are in effect
saying that it's about the object that that references points to, since
that's what a reference does.
Given a reference to an object instance of the class Sub, you still do not
know what static method is going to be called when you see this:

It would be different if the variable had been declared as
Super sub = new Sub();
than if it were
Sub sub = new Sub();
So the reference is the same in both cases (a sub object), but it is the
class that it is declared as (or casted to as you point out) that matters.
The reference by itself isn't enough. The compiler looks to see which class
is used.

Yes, that's true. But look at this:

Super sub = new Sub();
sub.staticmethod(); /* calls Super.staticmethod() */
((Sub)sub).staticmethod(); /* calls Sub.staticmethod() */

The same would work if sub==null. (I don't know if it would work if
sub were a Super object.)

Notice that the type of the variable sub is Super, yet the second
line calls Sub.staticmethod(). This shows that it is the reference
value (Sub)sub, not the variable sub, that controls which class is
used.

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"I said 'play as you've never played before', not 'play as IF you've never
played before'!"
- Andy Capp
 
T

Thomas G. Marshall

Joona I Palaste coughed up:
Thomas G. Marshall








Yes, that's true. But look at this:

Super sub = new Sub();
sub.staticmethod(); /* calls Super.staticmethod() */
((Sub)sub).staticmethod(); /* calls Sub.staticmethod() */

Of course.

The same would work if sub==null. (I don't know if it would work if
sub were a Super object.)

Notice that the type of the variable sub is Super, yet the second
line calls Sub.staticmethod(). This shows that it is the reference
value (Sub)sub, not the variable sub, that controls which class is
used.

Ok. If you wish to refer to (Sub)sub as merely a reference value then sure,
I suppose. It is more than that. It's a reference to sub with a contextual
declaration (or in this case a cast) indicating which /class/ the compiler
should use for its class-context. The mere fact that null could be used (as
we've all pointed out) is clear evidence that it /isn't/ about the
reference.

The point I was making is that sub is a reference to a Sub object. But that
is simply not enough. How does the compiler know? By the declaration of
the variable, or cast, used to identify the class in question. I should not
have said "variable", but "declaration or cast". But again, I've pointed
that out already.
 
G

Gary Labowitz

Thomas G. Marshall said:
Gary Labowitz coughed up:

No, you're wrong, and you've made it even more confusing.

1. Static data OR METHODS are referred to based upon the /declaration/ of
the Class (of the reference variable for example).

2. Non static data are ALSO referred to based upon the declaration of the
Class.

3. Non static methods are referred to based upon the type of the
polymorphized object underneath.

I guess I have to be more precise. At the point where we are talking about
this resolution issue the students haven't even gotten to static modifier
yet. So, I think what I am saying is correct for them. However, your three
point statement holds one area that I don't like. "3. ... polymorphized
object ..." gives me a problem. Since we haven't covered static, and I think
haven't covered overriding yet mention of polymorphism isn't useful. So, I
still want to default back to my two statements, let them program a while
and see the results, and then we introduce other notions. The first being
static, the next being inheritance, and then overriding inherited methods to
achieve polymorphism. They are already familiar with "stuctural
polymorphism" due to overloading. Anyway, I'm still struggling to find the
perfect way to introduce all topics simultaneously -- maybe just pass out
the JLS and tell them to memorize it.
 
G

Gary Labowitz

Lee Fesperman said:
Thomas said:
Lee Fesperman coughed up:
Thomas G. Marshall wrote:

Michael Borgwardt coughed up:
Thomas G. Marshall wrote:
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*

[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.

Your example is good, and it's one I've used before, except that your
explanation is missing how the thing is declared, which is why it isn't
about the reference.

The variable is declared with a type somewhere, or passed in as a formal
parameter of some type, etc. It is that type that determines the static
used, not the actual polymorphised object underneath.

You completely missed my point. It is about the reference. A variable is not necessary.
There is no 'thing' declared. Try these:

I'm going to hit you with my semantic issue. There "sorta" is a variable
involved, but it is a "constant variable" over there in the literal pool.
And the constant variables in the literal pool have type.

How's that for weaseling??
 

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,263
Messages
2,571,062
Members
48,769
Latest member
Clifft

Latest Threads

Top