f



When is an error not an error?

The Java language specification claims in:
8.8.7.1 Explicit Constructor Invocations
....
"If an anonymous class instance creation expression appears within an explicit 
constructor invocation statement, then the anonymous class may not refer to any 
of the enclosing instances of the class whose constructor is being invoked."

Helpfully it gives an example:

"For example:


     class Top {
        int x;
        class Dummy {
           Dummy(Object o) {}
        }
        class Inside extends Dummy {
           Inside() {
              super(new Object() { int r = x; }); // error
           }
           Inside(final int y) {
              super(new Object() { int r = y; }); // correct
           }
        }
     }
"
Notice the word 'error' in the comment. This example compiles without error and 
produces the correct code. In what sense is it an 'error'? It is not a compiler 
error, it is not a runtime error. To quote Douglas Adams "this must be some new 
meaning of the word 'error' with which I am unfamiliar". Any idea what's gone 
wrong?

0
11/4/2008 2:00:37 PM
comp.lang.java.programmer 52714 articles. 1 followers. Post Follow

10 Replies
4829 Views

Similar Articles

[PageSpeed] 16

In article <gepkhr$rop$1$8302bc10@news.demon.co.uk>,
 Anon <blackhole@nowhere.com> wrote:

> The Java language specification claims in:
> 8.8.7.1 Explicit Constructor Invocations

[<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.8.
7.1>]

> Notice the word 'error' in the comment. This example compiles without 
> error and produces the correct code. In what sense is it an 'error'? 
[...]

Upon instantiation, I get an error trying to refer to this.x:

4: non-static variable this cannot be referenced from a static context

<sscce>
class Top {
   int x;
   public static void main(String[] args) {
      new Inside();
   }
   class Dummy {
      Dummy(Object o) {}
   }
   class Inside extends Dummy {
      Inside() {
         super(new Object() { int r = x; }); // error
      }
      Inside(final int y) {
         super(new Object() { int r = y; }); // correct
      }
   }
}
</sscce>

-- 
John B. Matthews
trashgod at gmail dot com
http://home.roadrunner.com/~jbmatthews/
0
nospam59 (11088)
11/4/2008 6:12:55 PM
John B. Matthews wrote:

> Upon instantiation, I get an error trying to refer to this.x:

Odd.  My IDE (NetBeans) gives no error and runs it fine.  What version 
on the JDK are you using? Mine is 1.6.0.


Here's my SSCCE, because I needed a main method.  The original source 
has been reformatted by my IDE, but it's just a cut and paste from the 
source in the OP, with an added main() method and testIt().


package jlserrortest;

class Top
{
     int x;


     class Dummy
     {
         Dummy( Object o )
         {
         }
     }

     class Inside extends Dummy
     {
         Inside()
         {
             super( new Object()
             {
                 int r = x;
             } ); // error
         }

         Inside( final int y )
         {
             super( new Object()
             {
                 int r = y;
             } ); // correct
         }
     }

     public static void main (String ... args ) {
         new Top().testIt();
     }

     private void testIt()
     {
         Inside i1 = new Inside();
         Inside i2 = new Inside( 10 );
         System.out.println( "hash: " + (i1.hashCode() + i2.hashCode()) );
     }
}

init:
deps-jar:
Created dir: C:\Users\Dev\misc\JLSErrorTest\build\classes
Compiling 1 source file to C:\Users\Dev\misc\JLSErrorTest\build\classes
compile:
run:
hash: 11276738
BUILD SUCCESSFUL (total time: 1 second)
0
markspace1 (668)
11/4/2008 6:58:22 PM
On 4 Nov, 18:12, "John B. Matthews" <nos...@nospam.invalid> wrote:
> In article <gepkhr$rop$1$8302b...@news.demon.co.uk>,
>
> =A0Anon <blackh...@nowhere.com> wrote:
> > The Java language specification claims in:
> > 8.8.7.1 Explicit Constructor Invocations
>
> [<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.8.
> 7.1>]
>
> > Notice the word 'error' in the comment. This example compiles without
> > error and produces the correct code. In what sense is it an 'error'?
>
> [...]
>
> Upon instantiation, I get an error trying to refer to this.x:
>
> 4: non-static variable this cannot be referenced from a static context

Quite correct you have not created an enclosing instance of Top
therefore it attempts to use 'this' as the enclosing instance when you
create Inside. You can't use 'this' in a static method. (main is
static).

Try 'new Top().new Inside();' instead of 'new Inside();'

>
> <sscce>
> class Top {
> =A0 =A0int x;
> =A0 =A0public static void main(String[] args) {
> =A0 =A0 =A0 new Inside();
> =A0 =A0}
> =A0 =A0class Dummy {
> =A0 =A0 =A0 Dummy(Object o) {}
> =A0 =A0}
> =A0 =A0class Inside extends Dummy {
> =A0 =A0 =A0 Inside() {
> =A0 =A0 =A0 =A0 =A0super(new Object() { int r =3D x; }); // error
> =A0 =A0 =A0 }
> =A0 =A0 =A0 Inside(final int y) {
> =A0 =A0 =A0 =A0 =A0super(new Object() { int r =3D y; }); // correct
> =A0 =A0 =A0 }
> =A0 =A0}}
>
> </sscce>
>
0
11/4/2008 10:04:27 PM
In article <geq614$gbb$1@registered.motzarella.org>,
 Mark Space <markspace@sbcglobal.net> wrote:

> John B. Matthews wrote:
> 
> > Upon instantiation, I get an error trying to refer to this.x:
> 
> Odd.  My IDE (NetBeans) gives no error and runs it fine.  What version 
> on the JDK are you using? Mine is 1.6.0.
> 
> 
> Here's my SSCCE, because I needed a main method.  The original source 
> has been reformatted by my IDE, but it's just a cut and paste from the 
> source in the OP, with an added main() method and testIt().

Ah, thank you. On 1.5.0_16, NetBeans 6.1, using your sscce, I get the 
same result. The main in my sscce instantiated Inside directly, in a 
static context:

   public static void main(String[] args) {
      new Inside();
   }

This version, more like yours, compiles & runs fine:

   public static void main(String[] args) {
      new Top();
   }

I suspect this is not the error the OP & JLS mention.

[...]

-- 
John B. Matthews
trashgod at gmail dot com
http://home.roadrunner.com/~jbmatthews/
0
nospam59 (11088)
11/4/2008 10:39:32 PM
In article 
<c684c650-8017-4bd5-920b-819b9b940522@q26g2000prq.googlegroups.com>,
 Scott.Clive.A@googlemail.com wrote:

> On 4 Nov, 18:12, "John B. Matthews" <nos...@nospam.invalid> wrote:
> > In article <gepkhr$rop$1$8302b...@news.demon.co.uk>,
> >
> > ´┐ŻAnon <blackh...@nowhere.com> wrote:
> > > The Java language specification claims in:
> > > 8.8.7.1 Explicit Constructor Invocations
> >
> > [<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.8.
> > 7.1>]
> >
> > > Notice the word 'error' in the comment. This example compiles without
> > > error and produces the correct code. In what sense is it an 'error'?
> >
> > [...]
> >
> > Upon instantiation, I get an error trying to refer to this.x:
> >
> > 4: non-static variable this cannot be referenced from a static context
> 
> Quite correct you have not created an enclosing instance of Top
> therefore it attempts to use 'this' as the enclosing instance when you
> create Inside. You can't use 'this' in a static method. (main is
> static).
> 
> Try 'new Top().new Inside();' instead of 'new Inside();'

Thanks, I see what you mean. I saw "this" and thought "this.x".

I guess the OP's question remains.

-- 
John B. Matthews
trashgod at gmail dot com
http://home.roadrunner.com/~jbmatthews/
0
nospam59 (11088)
11/4/2008 10:44:13 PM
When it's a jar, of course!

-Wayne
0
Wayne
11/5/2008 7:46:02 AM
On 4 Nov, 22:44, "John B. Matthews" <nos...@nospam.invalid> wrote:
> In article
> <c684c650-8017-4bd5-920b-819b9b940...@q26g2000prq.googlegroups.com>,
>
>
>
> =A0Scott.Cliv...@googlemail.com wrote:
> > On 4 Nov, 18:12, "John B. Matthews" <nos...@nospam.invalid> wrote:
> > > In article <gepkhr$rop$1$8302b...@news.demon.co.uk>,
>
> > > =A0Anon <blackh...@nowhere.com> wrote:
> > > > The Java language specification claims in:
> > > > 8.8.7.1 Explicit Constructor Invocations
>
> > > [<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#=
8.8.
> > > 7.1>]
>
> > > > Notice the word 'error' in the comment. This example compiles witho=
ut
> > > > error and produces the correct code. In what sense is it an 'error'=
?
>
> > > [...]
>
> > > Upon instantiation, I get an error trying to refer to this.x:
>
> > > 4: non-static variable this cannot be referenced from a static contex=
t
>
> > Quite correct you have not created an enclosing instance of Top
> > therefore it attempts to use 'this' as the enclosing instance when you
> > create Inside. You can't use 'this' in a static method. (main is
> > static).
>
> > Try 'new Top().new Inside();' instead of 'new Inside();'
>
> Thanks, I see what you mean. I saw "this" and thought "this.x".
>
> I guess the OP's question remains.
>
> --
> John B. Matthews
> trashgod at gmail dot comhttp://home.roadrunner.com/~jbmatthews/

I wonder if there's a security hole here? Here's an example based on
the problem. Think you understand scope? Try this:
class Top {
	class Inside extends Dummy {
		Inside() {
			super(new Object() { Top t =3D Top.this;   class W{Top t =3D
Top.this;} });
		}
	}


}

class Dummy {
	Dummy(Object o) {}
}

This gives an error "4: no enclosing instance of type Top is in scope"
but the error is for class W. Remove the reference to Top.this from W
and it compiles fine. So Top.this is in scope in the directly
enclosing class of W but not W! W is not declared in a static context
so this must contradict scoping rules somewhere. Of course the
anonymous class is not supposed to have access to an instance of Top
because its declared in a static context - that would resolve the
contradiction.
0
11/5/2008 11:59:36 AM
On 5 Nov, 07:46, Wayne <nos...@all.4me.invalid> wrote:
> When it's a jar, of course!
>
> -Wayne

How about when its a compiler error!
class Top {
	int m() {return 42;};
	class Inside extends Dummy {
		Inside() {
			super(new Object() { int x=3Dm();   /*class W{int x=3Dm();}*/ });
		}
	}


}

class Dummy {
	Dummy(Object o) {}
}
That compiles fine. Yet
"15.12.4.1 Compute Target Reference (If Necessary)
.....

Otherwise, let T be the enclosing type declaration of which the method
is a member, and let n be an integer such that T is the nth lexically
enclosing type declaration (=A78.1.3) of the class whose declaration
immediately contains the method invocation. Then the target reference
is the nth lexically enclosing instance (=A78.1.3) of 'this'. It is a
compile-time error if the nth lexically enclosing instance (=A78.1.3) of
'this' does not exist.
...."

T corresponds to Top, n is 2. [What it's doing it looking at each
enclosing class and trying to find the corresponding enclosing
instance of that class.]

"8.1.3 ...
An instance of an inner class I whose declaration occurs in a static
context has no lexically enclosing instances. However, if I is
immediately declared within a static method or static initializer then
I does have an enclosing block, which is the innermost block statement
lexically enclosing the declaration of I."

"A statement or expression occurs in a static context if and only if
the innermost method, constructor, instance initializer, static
initializer, field initializer, or explicit constructor invocation
statement enclosing the statement or expression is a static method, a
static initializer, the variable initializer of a static variable, or
an explicit constructor invocation statement (=A78.8.7)."

super(new Object() { int x=3Dm();}); is an explicit constructor
invocation statement. Therefore there are no lexically enclosing
instances, therefore it is a compile-time error. So why does it
compile without an error?

Uncomment the code for W and you'll see that unlike the anonymous
class, it is able to give a compile-time error. It determines that an
instance of Top is not in scope - yet it is supposedly in scope in the
directly enclosing class.



0
11/5/2008 2:02:16 PM
Scott.Clive.A@googlemail.com wrote:

> class Top {
> 	class Inside extends Dummy {
> 		Inside() {
> 			super(new Object() { Top t = Top.this;   class W{Top t =
> Top.this;} });

> 
> This gives an error "4: no enclosing instance of type Top is in scope"
> but the error is for class W. Remove the reference to Top.this from W

I think that's because W is a local class and implicitly static, which 
has no enclosing instance. See:

<http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.3>

I can't find the section on use of "this" keyword right now, and my 
search fu is weak apparently.  But that's my guess.


0
markspace1 (668)
11/5/2008 8:47:37 PM
On 5 Nov, 20:47, Mark Space <marksp...@sbcglobal.net> wrote:
> Scott.Cliv...@googlemail.com wrote:
> > class Top {
> > =A0 =A0class Inside extends Dummy {
> > =A0 =A0 =A0 =A0 =A0 =A0Inside() {
> > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0super(new Object() { Top t =3D T=
op.this; =A0 class W{Top t =3D
> > Top.this;} });
>
> > This gives an error "4: no enclosing instance of type Top is in scope"
> > but the error is for class W. Remove the reference to Top.this from W
>
> I think that's because W is a local class and implicitly static, which
> has no enclosing instance. See:
>
> <http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.1.3=
>

Nice try but it's easy to prove that W is not implicitly static. If it
was implicitly static you would not be able to access instance methods
or fields in the anonymous class. Just add an instance field to the
anonymous class, you'll have no difficulty accessing it from W.

The class which is implicitly static is the anonymous class (that's
because it is created inside the super( ) call). The problem is Javac
doesn't handle that properly, there is no enclosing instance of Top or
Inside (because its implicitly static) therefore access to any
instance member in either of those classes by the anonymous class
ought to give a compile time error.

W actually has the correct behaviour - according to the Java Language
specification. The problem is the anonymous class.

[BTW W is defined as a member of the anonymous class and is therefore
an inner member class rather than a local class. Local classes are
local to a method, constructor or initializer].

>
> I can't find the section on use of "this" keyword right now, and my
> search fu is weak apparently. =A0But that's my guess.

0
11/5/2008 11:02:27 PM
Reply:

Web resources about - When is an error not an error? - comp.lang.java.programmer

Error - Wikipedia, the free encyclopedia
The word error entails different meanings and usages relative to how it is conceptually applied. The concrete meaning of the Latin word "error" ...

Scott Morrison under fire after BIS Shrapnel report used to attack Labor contained crucial error
... negative gearing policy, after the report's authors clarified it was prepared before Labor's policy was announced and contained crucial errors. ...

Scott Morrison under fire after BIS Shrapnel report used to attack Labor contained crucial error
... negative gearing policy, after the report's authors clarified it was prepared before Labor's policy was announced and contained crucial errors. ...

Porsche sees error of ways, next 911 GT3 to offer manual transmission
Filed under: Porsche , Coupe , Performance The man behind the Porsche 911 GT3 says the next generation of the high performer will get an optional ...

Coding error leads to data leak at WMT
The error happened during the migration of servers and was not a hack, a company spokesman said.

Lee Daniels Admits 'Empire' Suffered From 'Growing Pains' in Season 2: 'It's Trial and Error'
Lee Daniels Admits 'Empire' Suffered From 'Growing Pains' in Season 2: 'It's Trial and Error'

80004005: Why Error Messages Are Still So *&%$#! Indecipherable
... There's a good chance the engineers are too. If you've ever been vexed by a phone, tablet, or PC, chances are you've bumped into an error code. ...

A Basic Spelling Error Cost These Hackers Nearly $1 Billion
Most spelling mistakes are innocent, fleeting, and only mildly embarrassing. Then there are the ones that result in a loss of over $800 million ...

Errors Blamed for No Quick Fix of Early Prison Releases
A nearly two-month investigation into the early release of prisoners over a 13-year period found a series of missteps within the Department of ...

ign.com - 500 Server Error
ign.com - 500 Server Error

Resources last updated: 3/16/2016 1:27:45 AM