Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Java > Inner Classes a liability

Reply
Thread Tools

Inner Classes a liability

 
 
Robert
Guest
Posts: n/a
 
      04-26-2004
Ben Wilson wrote:

> Hi, I'm hoping someone out there is an expert and can share some
> authoritative insights.
>
> I'm working with inner classes in Java, and I'm finding myself unsatisfied
> with the way they've been implemented, and frankly, somewhat alarmed. It is
> true that an inner class can access the methods and object variables of its
> enclosing class. However, it is also true that inner classes participate in
> overriding - I can set up an inner class that overrides the members of its
> enclosing class. However, inner classes can also be defined to extend
> another class entirely.
>
> Hello? I thought Java didn't support multiple inheritance but here it is!
>
> Have a look at this sample code and tell me what's going on here:
>
> //inners2.java
>
> class inners2
> {
> void printMessage()
> {
> System.out.println("ladida");
> }
>
> public static void main(String[] args)
> {
> new outerclass01().new sucker().printMessage();
> }
> }
>
> class outerclass01
> {
> void printMessage()
> {
> System.out.println("humdeedum");
> }
>
> class sucker extends inners2
> {}
> }
>
> So there you go, what's the above code going to print when run? Is it
> "ladida" or "humdeedum"?
>
> From seeing this I get the feeling that not a lot of thought got put into
> defining what it was exactly that inner classes were supposed to do. Anybody
> know what the story is here?
>
> Thanks,
>
> Ben.
>

Maybe good timing on JDJ's part.

There is an article called "Strategies for Securing Java Code". Rule #1
is "Avoid Using Inner Classes". A good read and here is the link to it:

http://sys-con.com/story/?storyid=44375&DE=1
 
Reply With Quote
 
 
 
 
Christophe Vanfleteren
Guest
Posts: n/a
 
      04-26-2004

> Maybe good timing on JDJ's part.
>
> There is an article called "Strategies for Securing Java Code". Rule #1
> is "Avoid Using Inner Classes". A good read and here is the link to it:
>
> http://sys-con.com/story/?storyid=44375&DE=1


Unfortunately, that article is full of flaws itself.

http://www.theserverside.com/news/th...hread_id=25522
http://www.neward.net/ted/weblog/ind...#1082938072837

--
Kind regards,
Christophe Vanfleteren
 
Reply With Quote
 
 
 
 
Chris Smith
Guest
Posts: n/a
 
      04-27-2004
Robert wrote:
> Maybe good timing on JDJ's part.
>
> There is an article called "Strategies for Securing Java Code". Rule #1
> is "Avoid Using Inner Classes". A good read and here is the link to it:
>
> http://sys-con.com/story/?storyid=44375&DE=1


Or perhaps a really bad article. I don't read JDJ much, so I'm
struggling not to judge the whole magazine on the fact that this load of
balogna got through their editing process...

I'll constrain my criticism to the inner classes issue. In particular,
the article makes a few assumptions:

1. That package access is insecure. Aside from the inconsequential
misinformation about the treatment of private field access from inner
classes (which really is inconsequential, as the result is a package-
access member either way), there's nothing wrong with package access for
security!

I'd go as far as saying that anything stronger than package access
(i.e., private access) is nice from a code maintenance standpoint, but
absolutely pointless to someone concerned about security. The authors
say they are concerned about package access because someone could
conceivably provide code that declares the same package as the security-
sensitive code. The authors mention package-sealing... that security
feature that's used effectively by the *entire* core API to prevent
exactly these kinds of security issues... but imply that it's a "second-
best" kind of answer. Not the case; if you want to secure access by
untrusted code to an API, it *has* to be in a sealed package.

The only remaining possibility, then, is concern about someone replacing
the existing implementation... a task which requires the kind of access
to the system that makes security completely moot!

Basically, if package access is broken from a security standpoint, then
Java is broken from a security standpoint. So if the authors really
believe what they say, then they need to stop using Java for security-
sensitive code. Of course, that won't really be necessary because they
are wrong.

2. The basic assumption that protection is needed against an attacker
running arbitrary bits of your code. This general concept fails
miserably. Any attacker who can run arbitrary bits of your code has
already won. Period. "Full stop" (if you're British). End of story.
If the authors are concerned about untrusted code running under a
security manager, then fine... but shouldn't they mention using the
security manager in that case?

Truth is, using inner classes is not a security risk. Failing to take
basic precautionary steps such as sealing security-sensitive packages in
the presence of untrusted code, on the other hand, is definitely a
security risk.

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

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
Reply With Quote
 
Chris Smith
Guest
Posts: n/a
 
      04-27-2004
Christophe Vanfleteren wrote:
> Unfortunately, that article is full of flaws itself.
>
> http://www.theserverside.com/news/th...hread_id=25522
> http://www.neward.net/ted/weblog/ind...#1082938072837


Oops, should have read this before I wrote my long reply a second ago...

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

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
Reply With Quote
 
Robert
Guest
Posts: n/a
 
      04-27-2004
Chris Smith wrote:

> Christophe Vanfleteren wrote:
>
>>Unfortunately, that article is full of flaws itself.
>>
>>http://www.theserverside.com/news/th...hread_id=25522
>>http://www.neward.net/ted/weblog/ind...#1082938072837

>
>
> Oops, should have read this before I wrote my long reply a second ago...
>

Ah yes, I had not seen those either. Hmmm.
 
Reply With Quote
 
Ben Wilson
Guest
Posts: n/a
 
      04-27-2004
To everyone who has helped me by replying to this, thank you!

My confusion started with the explanation of inner classes as "getting
access to the members of its enclosing class". From this I assumed that this
access was just made available, also to the inner class's callable
interface. In other words, I thought it was bigger than it actually was.

To use the example from Chris Smith:

public class Test
{
public static void main(String[] args)
{
new Test2().new TestInner().printMessage();
}
}

class Test2
{
public void printMessage()
{
System.out.println("Test message");
}

class TestInner
{
}
}


Yes, I can see now that this doesn't work. However, the call here to
printMessage(), had it been done within the class TestInner, would have.

The principles of "hiding" members from the outer class from within the
inner class have many parallels with overriding, so it is easy to get
confused. My dissatisfaction started because I realised I could "hide" a
method from the outer class by making one with an identical signature from
an inner class, but once I did that I could never actually get a-hold of the
outer class with something like "super". But more about this later.

First, two observations:
First observation: the literature makes a *real* lousy job of explaining
this. Take Heller&Roberts book "Complete Java 2 Certification Study Guide
Fourth Edition". When they talk about reusing method names, very
specifically, they say "As you construct classes and add methods to them, in
some circumstances you will want to re-use the same name for a method. You
can do so two ways with Java. Re-using the same method name with different
arguments and perhaps a different return type is known as overloading. Using
the same method name with identical arguments and return type is known as
overriding." Apparantly this statement is incorrect or at best incomplete -
there is also this "hiding" thing. Since what I was doing was using the same
method name with identical arguments and return type, well, it just *had* to
be overriding, right? Well, sure shows me!

As a second example, take Peter van der Linden's book "Just Java 2 - Fifth
edition". He says, in his chapter on Polymorphism: "Polymorphism is a
complicated name for a straightforward concept. It is Greek for 'many
shapes' and it merely means using the same one name to refer to different
methods. 'Name reuse' would be a better term. There are two types of
polymorphism in Java: the really easy kind (overloading) and the interesting
kind (overriding)." Same thing here, there's nothing on this hiding trick
you do with inner classes.

Second observation, this "hiding" principle is still iffy. Even if it it's
true that an inner class does not override the methods of its outer class
(as Chris and others have demonstrated) still it is possible for an inner
class to extend one of the methods of the outer class, much like a subclass
would do for its parent. Fortunately I read a bit from Bruce Eckel's book
where he explains this - and I've made a sample program to demonstrate:

package temptests;

class inners2
{

void printMessage()
{
System.out.println("hidiho");
}

public static void main(String[] args)
{

outerclass01 oc001 = new outerclass01();
outerclass01.sucker t2 = oc001.new sucker();
t2.lemmeSee();

}
}


class outerclass01
{

void printMessage()
{
System.out.println("deedledeedledeedle");
}

class sucker extends inners2
{

void printMessage()
{
System.out.println("feefifofum");
}

void lemmeSee()
{
printMessage();
super.printMessage();
outerclass01.this.printMessage();
}

}

}


The output is "feefifofum" "hidiho" and "deedledeedledeedle". This mechanism
enables me to extend methods with identical names, coming from two wholly
unrelated classes (outerclass01 and inners2). While it's great that this
sort of stuff is possible, I do believe, however, that it violates the
spirit of what they were trying to do when they specified no multiple
inheritance in Java.

I would be interested if somebody strongly disagreed with this.

Thanks,

Ben.





"Ben Wilson" <(E-Mail Removed)> skrytta an brickt
news:408c4b31$0$10808$(E-Mail Removed)...
> Hi, I'm hoping someone out there is an expert and can share some
> authoritative insights.
>
> I'm working with inner classes in Java, and I'm finding myself unsatisfied
> with the way they've been implemented, and frankly, somewhat alarmed. It

is
> true that an inner class can access the methods and object variables of

its
> enclosing class. However, it is also true that inner classes participate

in
> overriding - I can set up an inner class that overrides the members of its
> enclosing class. However, inner classes can also be defined to extend
> another class entirely.
>
> Hello? I thought Java didn't support multiple inheritance but here it is!
>
> Have a look at this sample code and tell me what's going on here:
>
> //inners2.java
>
> class inners2
> {
> void printMessage()
> {
> System.out.println("ladida");
> }
>
> public static void main(String[] args)
> {
> new outerclass01().new sucker().printMessage();
> }
> }
>
> class outerclass01
> {
> void printMessage()
> {
> System.out.println("humdeedum");
> }
>
> class sucker extends inners2
> {}
> }
>
> So there you go, what's the above code going to print when run? Is it
> "ladida" or "humdeedum"?
>
> From seeing this I get the feeling that not a lot of thought got put into
> defining what it was exactly that inner classes were supposed to do.

Anybody
> know what the story is here?
>
> Thanks,
>
> Ben.
>
>
>
>



 
Reply With Quote
 
Tony Morris
Guest
Posts: n/a
 
      04-27-2004
It was I who posted that case, and it was to demonstrate the question:
"Are private members inherited ?"

--
Tony Morris
(BInfTech, Cert 3 I.T.)
Software Engineer
(2003 VTR1000F)
Sun Certified Programmer for the Java 2 Platform (1.4)
Sun Certified Developer for the Java 2 Platform


"Adam" <(E-Mail Removed)> wrote in message
news:c6ictd$blf$(E-Mail Removed)...
> > I do not believe Java was supposed to let this sort of thing happen.

> From
> > seeing this I get the feeling that not a lot of thought got put into
> > defining what it was exactly that inner classes were supposed to do.

> Anybody
> > know what the story is here?

>
> I'm having the same reservations about inner classes and
> their possibilities. Once someone posted such a riddle here
> (see below). I think it shows how bug prone can inner
> (in this case - anonymous) classes be:
>
> public class T
> {
> private final String name;
> protected void prname() { System.out.println(name); }
> T(String name) { this.name = name; }
>
> public static void main(String[] args)
> {
> new T("main").doit();
> }
>
> private void doit()
> {
> new T("anonymous inner")
> {
> void method()
> {
> prname();
> }
> }.method();
> }
> }
>
> What will be printed when you run it?
>
>



 
Reply With Quote
 
Adam
Guest
Posts: n/a
 
      04-27-2004

"Tony Morris" <(E-Mail Removed)> wrote in message
news:c6kv7b$ma2$(E-Mail Removed)...
> It was I who posted that case, and it was to demonstrate the

question:
> "Are private members inherited ?"


Sorry, Tony for not mentioning you. I just could'n remember.
Anyway, it's a great example for this topic too,
presenting confusion that may arise when
using inner/anonymous classes.

Adam


 
Reply With Quote
 
Chris Smith
Guest
Posts: n/a
 
      04-27-2004
Ben Wilson wrote:
> First, two observations:
> First observation: the literature makes a *real* lousy job of explaining
> this.


Yes, indeed. For many of us who've been around since Java 1.0.2 (and
that includes many of those who write books), it seems natural to
describe the old behavior of classes as "normal", and just know that
nested/inner classes are the exception. It's a bad habit, and should be
broken. You'll see the same thing regarding access specifiers: many
books will give you a blanket statement that classes can only have
public or package access, and then mention in chapter 17 somewhere that
nested classes can have the full range of private, package, protected,
or public just like any other member.

It's good to get the difference between overriding and overloading down;
but it only applies in cases where you're working with instance methods
declared in a common supertype. For static methods, only overloading
applies. For outer class methods, I'd wonder if use of the word
"overloading" is justified... but the behavior is the same as if it
were. The difference in the latter is really only conceptual in nature.

> As a second example, take Peter van der Linden's book "Just Java 2 - Fifth
> edition". He says, in his chapter on Polymorphism: "Polymorphism is a
> complicated name for a straightforward concept. It is Greek for 'many
> shapes' and it merely means using the same one name to refer to different
> methods. 'Name reuse' would be a better term. There are two types of
> polymorphism in Java: the really easy kind (overloading) and the interesting
> kind (overriding)."


Well, frankly I don't know what Peter was thinking. I respect Peter's
opinion on most topics (and he used to be a fairly active participant in
this newsgroup), but this is just dead wrong. Polymorphism has nothing
to do with method overloading. It is the property of runtime dispatch
of overridden methods.

> Second observation, this "hiding" principle is still iffy. Even if it it's
> true that an inner class does not override the methods of its outer class
> (as Chris and others have demonstrated) still it is possible for an inner
> class to extend one of the methods of the outer class, much like a subclass
> would do for its parent.


I still disagree with the terminology here.

You should think of the ability of an inner class to call methods of its
outer class as a convenience offered to you by the compiler, and nothing
more. Any meaningful relationship between a method in an inner class
and a similarly named method in an outer class is a myth. Exactly like
any relationship between mutually overloaded methods is a myth. The
sooner you understand that, the sooner this will make sense to you.

In your example, there are exactly two classes that have a definite
relationship, and they are inners2 and sucker. outerclass01 is just
there, and is used by sucker to delegate a method call. That's it. The
fact that the method 'printMessage' in sucker/inners2 has the same name
and parameters as printMessage in outerclass01 is a coincidence. In
fact, it has the unfortunate side-effect that it's harder to actually
call that printMessage method, requiring you to use "OuterClass.this."
to resolve the ambiguity.

> The output is "feefifofum" "hidiho" and "deedledeedledeedle". This mechanism
> enables me to extend methods with identical names, coming from two wholly
> unrelated classes (outerclass01 and inners2). While it's great that this
> sort of stuff is possible, I do believe, however, that it violates the
> spirit of what they were trying to do when they specified no multiple
> inheritance in Java.


I really believe not. The similarity in name is coincidental, and has
no semantic significance. The purpose of disallowing multiple
inheritance in Java was to avoid overly complex method dispatch. There
is no dispatch here; the compiler knows entirely at compile-time exactly
which method you are calling.

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

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
Reply With Quote
 
John C. Bollinger
Guest
Posts: n/a
 
      04-27-2004
Ben Wilson wrote:
> My confusion started with the explanation of inner classes as "getting
> access to the members of its enclosing class". From this I assumed that this
> access was just made available, also to the inner class's callable
> interface. In other words, I thought it was bigger than it actually was.


[...]

> The principles of "hiding" members from the outer class from within the
> inner class have many parallels with overriding, so it is easy to get
> confused. My dissatisfaction started because I realised I could "hide" a
> method from the outer class by making one with an identical signature from
> an inner class, but once I did that I could never actually get a-hold of the
> outer class with something like "super". But more about this later.


Well, "super" itself doesn't work, and oughtn't, but a construct of the
form Outer.this does. You even offer your own example later.

> First, two observations:
> First observation: the literature makes a *real* lousy job of explaining
> this. Take Heller&Roberts book "Complete Java 2 Certification Study Guide
> Fourth Edition". When they talk about reusing method names, very
> specifically, they say "As you construct classes and add methods to them, in
> some circumstances you will want to re-use the same name for a method. You
> can do so two ways with Java. Re-using the same method name with different
> arguments and perhaps a different return type is known as overloading. Using
> the same method name with identical arguments and return type is known as
> overriding." Apparantly this statement is incorrect or at best incomplete -
> there is also this "hiding" thing. Since what I was doing was using the same
> method name with identical arguments and return type, well, it just *had* to
> be overriding, right? Well, sure shows me!


No, you are applying the statement too broadly. You seem to have not
grasped the fact that for all intents and purposes, an inner class is a
*seperate* class from its containing class[es]. It has special access
to its containing class[es], true, but that's irrelevant. When you add
a method to an inner class you are not adding it to any containing
class, so you H&R's statement does not apply.

> As a second example, take Peter van der Linden's book "Just Java 2 - Fifth
> edition". He says, in his chapter on Polymorphism: "Polymorphism is a
> complicated name for a straightforward concept. It is Greek for 'many
> shapes' and it merely means using the same one name to refer to different
> methods. 'Name reuse' would be a better term. There are two types of
> polymorphism in Java: the really easy kind (overloading) and the interesting
> kind (overriding)." Same thing here, there's nothing on this hiding trick
> you do with inner classes.


Again, same comment: methods on an inner class are not methods on any
containing class. Polymorphism is an aspect of relationships among
classes. Unless the inner class extends a containing class (rarely good
or appropriate) the concept of polymorphism is just not germane to the
relationship between inner classes and their containing classes.

> Second observation, this "hiding" principle is still iffy. Even if it it's
> true that an inner class does not override the methods of its outer class
> (as Chris and others have demonstrated) still it is possible for an inner
> class to extend one of the methods of the outer class, much like a subclass
> would do for its parent.


No. Perhaps we're having another terminology problem, but the word
"extend" has specific meaning in the context of Java: the relationships
between a class and each of its superclasses. As we've been discussing,
a class can override methods inherited from any class it extends, and it
can offer overloaded versions of those methods.

You are quite right that under certain circumstances an inner class may
override a method inherited from its superclass, which itself hides a
method of the containing class. The confusing mess that results is not
a language problem, it is a language usage problem. Good designs,
including those that use inner classes, do not exhibit such problems.
You can shoot yourself in the foot in any language (see
http://www-users.cs.york.ac.uk/~susan/joke/foot.htm, or any of the many
variations available on the web) but that doesn't mean that all computer
languages are therefore flawed.

John Bollinger
http://www.velocityreviews.com/forums/(E-Mail Removed)

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
failing to instantiate an inner class because of order of inner classes Pyenos Python 2 12-27-2006 11:19 PM
Debate: Inner classes or public classes with package access? Christian Bongiorno Java 5 08-30-2004 08:14 AM
What is the difference between nested classes and inner classes ? Razvan Java 5 07-27-2004 07:59 PM
How to access inner classes variables & methods from outer classes lonelyplanet999 Java 1 11-13-2003 01:54 PM
inner classes in python as inner classes in Java Carlo v. Dango Python 14 10-19-2003 08:49 AM



Advertisments