Win a copy of Event Streams in Action this week in the Java in General forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Devaka Cooray
  • Liutauras Vilda
  • Jeanne Boyarsky
  • Bear Bibeault
Sheriffs:
  • Paul Clapham
  • Knute Snortum
  • Rob Spoor
Saloon Keepers:
  • Tim Moores
  • Ron McLeod
  • Piet Souris
  • Stephan van Hulst
  • Carey Brown
Bartenders:
  • Tim Holloway
  • Frits Walraven
  • Ganesh Patekar

Inner Classes Constructors

 
Ranch Hand
Posts: 243
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

There are some complex rules for Inner Classes which I dont fully understand. If I have an OuterA class which has and InnerA class, then I can create instances of InnerA in a different class OuterB without much problem.
However if OuterB is in a different Package(sub), and you create and instance of OuterA in OuterB and then you try to create an InnerA as
OuterA outerA = new OuterA();
OuterA.InnerA innerA = outerA.new InnerA();
then the compiler gives a strange error :
"OuterB.java:6: No constructor matching OuterA.InnerA(sub.OuterA) found in inner
class sub.OuterA. InnerA.
OuterA.InnerA innerA = outerA.new InnerA();"
When I am not passing any OuterA in the constructor of InnerA then why is it searching for one and giving this error?

So I construct a constructor for InnerA which takes an OuterA as an argument. I also call super() on this instance of OuterA that I am passing.
package sub;
public class OuterA
{
public class InnerA
{ public InnerA(OuterA oa){
oa.super();
}
}

}

Now when I try to create the InnerA inside OuterB, I have to pass the SAME instance of OuterA which I am using to create the InnerA.(why can't compiler automatically use the instance of OuterA for which it is creating InnerA).
OuterA.InnerA innerA = outerA.new InnerA(outerA);
Now every thing seems to work fine. What is going on here??
 
Ranch Hand
Posts: 1953
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I've an answer probably you don't want to hear:
Please do not use inner class this way!
See a related discussion Don't use inner class unless it is a very simple case.

Roseanne
[This message has been edited by Roseanne Zhang (edited January 07, 2001).]
[This message has been edited by Roseanne Zhang (edited January 08, 2001).]
 
Ranch Hand
Posts: 221
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mohit,
I haven't delved too deeply into your question, but here's a couple of thoughts:
Instances of inner classes exist in the context of an enclosing instance, so that's probably what the compiler is talking about in the error message. An implicit, compiler-provided argument, perhaps? (Just speculating here, but it seems I read something about that once. Can't find it right now...)
I note that the error doesn't happen unless the invoking code is in a different package, which leads me to wonder about accessibility. Are <code>OuterA</code>, <code>OuterA.InnerA</code>, and <code>OuterA.InnerA.InnerA()</code> all <code>public</code>? I suspect that the implicit argument occurs in both cases (<code>OuterB</code> in the same package and in some other package).
If my speculations are correct, a better way to handle the problem would be by adjusting the access, not by creating a weird c'tor.
Finally, I'll note that although lots of people say (effectively) "don't use inner classes unless the situation is trivial", there are lots of cases where it's useful to instantiate or manipulate an inner class from outside its enclosing class (cf. <code>Map.Entry</code>, for one). IMO, there are at least two good reasons to create and use an inner class: to control the global namespace, and to create a class with access to the private members of its enclosing class. As a Java pgmr who regularly misses the power and expressiveness of C++, I'm a lot more inclined to use them for the second reason.
Jerry
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mohit - for your original problem, make sure that the OuterA contructor is declared public. Otherwise it isn't visible from outside the package. While you're at it, upgrade from jdk 1.2.2 to jdk 1.3 - you'll get a better error message in this case. Also jdk 1.2.2 has a few bugs where inner classes are concerned.
I agree with Jerry that inner classes can be useful. It's just that it's very easy to make things more complicated with them than they need to be. I will note that Map.Entry is not an inner class - it's a static member interface. (Inner classes are by definition non-static.) Static classes and interfaces are almost always OK IMO, as they simply clean up the namesape without requiring you to instantiate the outer class. I have yet to see a good use of an inner class outside its enclosing class - I imagine it's possible, but I haven't seen one yet.
 
Roseanne Zhang
Ranch Hand
Posts: 1953
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Inner class can be useful, true, so does the old goto. In certain case, goto can save you hundreds-lines of code. Even Java still keeps goto as a unused keyword.
Everything is a trade-off in software engineering, we cannot have it all. Can we?
Roseanne
Sorry, I might cause some misconception here. I'm not suggestting that we should use goto. I think that the use of inner class should be very much in control. ---edited by Roseanne

[This message has been edited by Roseanne Zhang (edited January 08, 2001).]
 
Consider Paul's rocket mass heater.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!