views:

612

answers:

7

I came across this questions on one of the online Java Tests. The options were 4,5,8 and any number of times.

I have only used one inner class, but have never tried multiple ones. I was wondering if anyone knows the answer.

+4  A: 

I tried on my own: The answer is any number of times. The following is my test class, I had no compilation errors.


public class Test {


    public Test ()
    {

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

    class Test2
    {
     class Test3
     {
      class Test4
      {
       class Test5{
        class Test6{
         class Test7{
          class Test8{
           class Test9
           {

           }
          }
         }
        }
       }
      }

     }

    }


}
Kushal Paudyal
If there was a limit, then that would've been a serious design flaw in the Java compiler.
LiraNuna
I only see eight levels of nesting there, because I don't think they'd count the outer class. So you should add Test10 to be certain.
Kevin Bourrillion
lol... makes sense, but I think I would cry if I ever ran across something like that "in the wild". :-)
cjstehno
If infinite nesting was supported, wouldn't it mean that the program would use infinite amount of memory in infinite amount of time?
UncleBens
9 is not infinity. See below for a correct answer.
Alex Feinman
+6  A: 

Hmmm. I know that the online Java test you refer to is a lousy one. Does that count?

(This is the kind of limit that is irrelevant in practical experience. A similarly ridiculously question would be, "What is the maximum length of a function in bytes?")

Greg D
Actually, that last limitation is important. It's entirely unimportant to *know* it, but it can byte you when you generate code automatically. I had an adventure game converter at one point which blew that limit :(
Jon Skeet
Are we allowed to answer "I think this depends on the filesystem?"
Dean J
@Jon: Touche. :) Only time I ran into a limit like that was when code reviewing an intern's VB6 code. Apparently VB6 only allowed 32K characters per function, so the intern had to add the `DoStuff2` and `DoStuff3` functions as well. (Not making those names up.)
Greg D
DeanJ: I think you're right. The limit I reached when I tested it was that the class name of the innermost class wasn't a valid filename. Error message and testing code posted as answer below.
Mark Byers
+1 for byte you...
Thorbjørn Ravn Andersen
JSP pages using static includes can blow the limit (IIRC, 1.6ish was going to allow larger sizes, but it was decided that code generators should generate better code instead).
Tom Hawtin - tackline
+6  A: 

It's a completely irrelevant question and I hope they weren't using the results for anything important. I guess the answer they were looking for was 'any number of times' but in practice there will be a limit in any given implementation of Java. If it's not defined directly it will be determined by something like the maximum file size, or some other (possibly undocumented) internal limit. The best way to find out is to try it.

Update: 30 works, but 300 gives this error:

A.java:3: error while writing B0.B1.B2.B3.B4.B5.B6.B7.B8.B9.B10.B11.B12.B13.B14.
B15.B16.B17.B18.B19.B20.B21.B22.B23.B24.B25.B26.B27.B28.B29.B30.B31.B32.B33.B34.
B35.B36.B37.B38.B39.B40.B41.B42.B43.B44.B45.B46.B47.B48.B49.B50.B51.B52.B53.B54.
B55.B56.B57.B58.B59.B60.B61.B62.B63.B64.B65.B66.B67.B68.B69.B70.B71.B72.B73.B74.
B75.B76.B77.B78.B79.B80.B81.B82.B83.B84.B85.B86.B87.B88.B89.B90.B91.B92.B93.B94.
B95.B96.B97.B98.B99.B100.B101.B102.B103.B104.B105.B106.B107.B108.B109.B110.B111.
B112.B113.B114.B115.B116.B117.B118.B119.B120.B121.B122.B123.B124.B125.B126.B127.
B128.B129.B130.B131.B132.B133.B134.B135.B136.B137.B138.B139.B140.B141.B142.B143.
B144.B145.B146.B147.B148.B149.B150.B151.B152.B153.B154.B155.B156.B157.B158.B159.
B160.B161.B162.B163.B164.B165.B166.B167.B168.B169.B170.B171.B172.B173.B174.B175.
B176.B177.B178.B179.B180.B181.B182.B183.B184.B185.B186.B187.B188.B189.B190.B191.
B192.B193.B194.B195.B196.B197.B198.B199.B200.B201.B202.B203.B204.B205.B206.B207.
B208.B209.B210.B211.B212.B213.B214.B215.B216.B217.B218.B219.B220.B221.B222.B223.
B224.B225.B226.B227.B228.B229.B230.B231.B232.B233.B234.B235.B236.B237.B238.B239.
B240.B241.B242.B243.B244.B245.B246.B247.B248.B249.B250.B251.B252.B253.B254.B255.
B256.B257.B258.B259.B260.B261.B262.B263.B264.B265.B266.B267.B268.B269.B270.B271.
B272.B273.B274.B275.B276.B277.B278.B279.B280.B281.B282.B283.B284.B285.B286.B287.
B288.B289.B290.B291.B292.B293.B294.B295.B296.B297.B298.B299: B0$B1$B2$B3$B4$B5$B
6$B7$B8$B9$B10$B11$B12$B13$B14$B15$B16$B17$B18$B19$B20$B21$B22$B23$B24$B25$B26$B
27$B28$B29$B30$B31$B32$B33$B34$B35$B36$B37$B38$B39$B40$B41$B42$B43$B44$B45$B46$B
47$B48$B49$B50$B51$B52$B53$B54$B55$B56$B57$B58$B59$B60$B61$B62$B63$B64$B65$B66$B
67$B68$B69$B70$B71$B72$B73$B74$B75$B76$B77$B78$B79$B80$B81$B82$B83$B84$B85$B86$B
87$B88$B89$B90$B91$B92$B93$B94$B95$B96$B97$B98$B99$B100$B101$B102$B103$B104$B105
$B106$B107$B108$B109$B110$B111$B112$B113$B114$B115$B116$B117$B118$B119$B120$B121
$B122$B123$B124$B125$B126$B127$B128$B129$B130$B131$B132$B133$B134$B135$B136$B137
$B138$B139$B140$B141$B142$B143$B144$B145$B146$B147$B148$B149$B150$B151$B152$B153
$B154$B155$B156$B157$B158$B159$B160$B161$B162$B163$B164$B165$B166$B167$B168$B169
$B170$B171$B172$B173$B174$B175$B176$B177$B178$B179$B180$B181$B182$B183$B184$B185
$B186$B187$B188$B189$B190$B191$B192$B193$B194$B195$B196$B197$B198$B199$B200$B201
$B202$B203$B204$B205$B206$B207$B208$B209$B210$B211$B212$B213$B214$B215$B216$B217
$B218$B219$B220$B221$B222$B223$B224$B225$B226$B227$B228$B229$B230$B231$B232$B233
$B234$B235$B236$B237$B238$B239$B240$B241$B242$B243$B244$B245$B246$B247$B248$B249
$B250$B251$B252$B253$B254$B255$B256$B257$B258$B259$B260$B261$B262$B263$B264$B265
$B266$B267$B268$B269$B270$B271$B272$B273$B274$B275$B276$B277$B278$B279$B280$B281
$B282$B283$B284$B285$B286$B287$B288$B289$B290$B291$B292$B293$B294$B295$B296$B297
$B298$B299.class (The filename, directory name, or volume label syntax is incorr
ect)

Code used to generate source (written in Python):

n = input()
print "class A{public static void main(String[] a){}}\n"
print ''.join("class B%d{" % x for x in range(n)) + '}' * n

Disappointing. I was actually hoping it would be a lot more. I wonder if it could get much further on another system which allows longer filenames.

Mark Byers
This is great Work. I really appreciate your effort.
Kushal Paudyal
I don't know if you did that on Windows, but a file absolute path on windows can have at max 256 (or 255 ?) characters. On Windows it definitely can't go that long, but on Unix, it might work better.
subtenante
Yes, this was on Windows. If someone wants to try it on Unix they are welcome to try to set a new record. A few more extra inner classes could be squeezed out by using shorter class names and taking advantage of the full allowed character set for class names.
Mark Byers
So you might have a much lower maximum, what is the highest number that works?
rsp
On my system I can get 65 using the script I posted. It would be a little more if I were more careful with generating the shortest possible classnames.
Mark Byers
D'oh: I can't delete the files it created. Windows says 'The file name(s) would be too long for the destination folder. You can shorten the file name and try again, or try a location that has a shorter path.' Not using recycle bin doesn't help. Renaming won't work. I can't move the files either. So be careful when testing this on Windows!
Mark Byers
Eventually solved by moving out all the other files from that directory, then deleting the entire directory. Whew!
Mark Byers
The limit may be deeper when the classes are in a jar file.
Thorbjørn Ravn Andersen
+1  A: 

A good programmer might be able to nest 8, but only Jon Skeet can nest an infinite number of classes.

Fabian Steeg
+3  A: 

The true answer is none of the above. Javac will of course allow arbitrary nesting, but the underlying file system and/or OS have restrictions. We found recently that during startup the JVM running a Glassfish Java EE application server instance will hold open files to each .class during loading/JIT compilation. If you're running CentOS Linux say, the default limit on open files/process is 1024, so if you have a lot of classes being loaded at once and don't set the ulimit -n to a higher value, the JVM will hit "too many open files". And @Mark Byers' example shows that the .class file names get very long and can hit the file system name length limit, if there is one.

Jim Ferrans
+1  A: 

As a follow-up to Mark's trial on windows - a bit silly but fun nonetheless - I did a trial on AIX 5.3.

91 subclasses deep is ok, number 92 results in the following error:

-rw-r--r--   1 root     system        12813 Nov 24 15:15 A.class
Main class=class A

count=90 class=A$B$C$D$E$F$G$H$I$J$K$L$M$N$O$P$Q$R$S$T$U$V$W$X$Y$Z$AA$AB$AC$AD$AE$AF$AG$AH$AI$AJ$AK$AL$AM$AN$AO$AP$AQ$AR$AS$AT$AU$AV$AW$AX$AY$AZ$BA$BB$BC$BD$BE$BF$BG$BH$BI$BJ$BK$BL$BM$BN$BO$BP$BQ$BR$BS$BT$BU$BV$BW$BX$BY$BZ$CA$CB$CC$CD$CE$CF$CG$CH$CI$CJ$CK$CL$CM

-rw-r--r--   1 root     system        13081 Nov 24 15:16 A.class
Main class=class A

count=91 class=A$B$C$D$E$F$G$H$I$J$K$L$M$N$O$P$Q$R$S$T$U$V$W$X$Y$Z$AA$AB$AC$AD$AE$AF$AG$AH$AI$AJ$AK$AL$AM$AN$AO$AP$AQ$AR$AS$AT$AU$AV$AW$AX$AY$AZ$BA$BB$BC$BD$BE$BF$BG$BH$BI$BJ$BK$BL$BM$BN$BO$BP$BQ$BR$BS$BT$BU$BV$BW$BX$BY$BZ$CA$CB$CC$CD$CE$CF$CG$CH$CI$CJ$CK$CL$CM$CN

A.java:93: error while writing A.B.C.D.E.F.G.H.I.J.K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.Z.AA.AB.AC.AD.AE.AF.AG.AH.AI.AJ.AK.AL.AM.AN.AO.AP.AQ.AR.AS.AT.AU.AV.AW.AX.AY.AZ.BA.BB.BC.BD.BE.BF.BG.BH.BI.BJ.BK.BL.BM.BN.BO.BP.BQ.BR.BS.BT.BU.BV.BW.BX.BY.BZ.CA.CB.CC.CD.CE.CF.CG.CH.CI.CJ.CK.CL.CM.CN.CO: A$B$C$D$E$F$G$H$I$J$K$L$M$N$O$P$Q$R$S$T$U$V$W$X$Y$Z$AA$AB$AC$AD$AE$AF$AG$AH$AI$AJ$AK$AL$AM$AN$AO$AP$AQ$AR$AS$AT$AU$AV$AW$AX$AY$AZ$BA$BB$BC$BD$BE$BF$BG$BH$BI$BJ$BK$BL$BM$BN$BO$BP$BQ$BR$BS$BT$BU$BV$BW$BX$BY$BZ$CA$CB$CC$CD$CE$CF$CG$CH$CI$CJ$CK$CL$CM$CN$CO.class (A file or path name is too long.)
static class CO {
       ^
1 error

The generated Java source looks like:

class A {
  static class B {
    void run() { 
      System.out.println("count=" + 2 + " class=" + B.class.getName() + "\n"); 
    }
  }

  public static void main(String[] a){
    System.out.println("Main class=" + A.class + "\n");
    (new A.B()).run();
  }
}
rsp
A: 

yes there r infinite times we can nest a class

anil