This week's book giveaway is in the Clojure forum.
We're giving away four copies of Clojure in Action and have Amit Rathore and Francis Avila on-line!
See this thread for details.
Win a copy of Clojure in Action this week in the Clojure forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Violation of Inner-Outer rules???

 
Dan Temple
Ranch Hand
Posts: 93
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Does anyone know why this code works?
abstract class AbClass { public abstract void m(); }
public class OuterClass
{
public static AbClass getClass()
{
return new AbClass()
{
public void m() { }
};
}
}
An anonymous class is being created in the static method getClass(), but it is being created witout any instance of the Outer class? I thought this was never allowed ...
Dan
 
BJ Grau
Ranch Hand
Posts: 234
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This code looks OK to me.
Maybe you are thinking of member inner classes, which must always be associated with an instance of the outer class.
 
Dan Temple
Ranch Hand
Posts: 93
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But I don't understand the difference. I thought local method classes also needed an instance of the outer class, otherwise how could they have access to outer member fields?
Dan
 
Cindy Glass
"The Hood"
Sheriff
Posts: 8521
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well this code won;t work if you leave the method name getClass because you are attempting to hide the getClass method inherited from Object, which is also final so you can't override it, and it has an incorrect return type for getClass.
However, if you change the name to getABClass (or something) it will work.
Because the method that is holding it is static, the rules are slightly different.
From the JLS
8.1.2 Inner Classes and Enclosing Instances

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.

 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
There is a widespread myth that an inner class will always have an instance of its enclosing class. It simply isn't true, as Cindy's JLS quote above shows.
> I thought local method classes also needed an instance of the
> outer class, otherwise how could they have access to outer
> member fields?
If declared in a static context, a local class doesn't have access to outer member fields. You never have access to outer member fields inside a static method, for example, unless you explicitly create an instance and use that to access the fields.
 
Dan Temple
Ranch Hand
Posts: 93
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
But this is exactly my point. The anonymous class since it is defined in a static method has no enclosing instance related to it. Thus it cannot refer to any enclosing instance fields. But all inner classes except for static inner classes must have such an enclosing instance. But the above code with the anonymous class seems to violate this rule.
Dan
 
Cindy Glass
"The Hood"
Sheriff
Posts: 8521
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Dan Temple:
But all inner classes except for static inner classes must have such an enclosing instance.

No Dan, you are wrong. Read the JLS quote above carefully. It specifically says that if the inner class is in a static context then you DO NOT need to have an instance of the outer class.
That is also what Jim carefully explained.
 
Dan Temple
Ranch Hand
Posts: 93
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Okay ... I guess this was a fundamental misunderstanding on my part. So except for accessing final local variables, an inner class defined inside a static context is very similar to a static inner class. Correct?
Dan
 
It is sorta covered in the JavaRanch Style Guide.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic