16

Still coming from C++ I find it cumbersome to create many small helper classes and objects. Mostly because I have to have one file per class. I basically have a class like this:

public class mySimpleClass {
    public float[] numbers = new float[ 4 ];
}

And then I have this class:

public class myNotSoSimpleClass {
    private mySimpleClass;
    .
    .
    .
}

The second class which is not so simple is ok to have in its own file. However, the simple class is connected to the not so simple class and it would be very nice to not have to have those few lines of code in its own file.

So to sum it up, this is what one could do in C++:

public class myNotSoSimpleClass {
    private struct mySimpleClass {
        float numbers[ 4 ];
    } myStruct;
    .
    .
    .
}

Is it possible to embed/use one class inside another class, or the same file? I would just find it easier to work with large projects if I could set up these two classes into one file. Or is Java a strictly one class per file, and that's it, language?

Buhake Sindi
  • 87,898
  • 29
  • 167
  • 228
Espen
  • 3,607
  • 11
  • 48
  • 75
  • 5
    In Java, it is customary to name all class names with a capital letter and all variable names with a lowercase letter. You should call your classes `MySimpleClass` and `MyNotSoSimpleClass`. – Erick Robertson Nov 10 '10 at 14:21
  • 1
    Why do you have a class that does nothing except wrap an array, which is also a class? – JeremyP Nov 10 '10 at 15:36
  • @JeremyP: It's an example. My actual simple class has a few variables, and my not so simple class has much more code, including functions. – Espen Nov 10 '10 at 15:58
  • +1 However, the title asks for reasons in design decisions, why the question body asks for a way to do what you want. You could amplify the title to more accurately reflect what the question is about. – n611x007 Oct 24 '13 at 11:10

9 Answers9

17

You can have multiple classes in the same file, but only one of them can be public:

Java: Multiple class declarations in one file

frogatto
  • 28,539
  • 11
  • 83
  • 129
Mark Bell
  • 384
  • 2
  • 8
  • You can have public inner classes, what are you trying to say? – Buhake Sindi Nov 10 '10 at 14:09
  • 7
    He's not referring to inner classes at all, but additional top level classes. – Sean Reilly Nov 10 '10 at 14:10
  • "Only one of them can be public" is incorrect. – Andy Thomas Nov 10 '10 at 14:27
  • 3
    @Andy: No, "Only one of them can be public" is perfectly correct. Further I can't understand why this was downvoted. – chiccodoro Nov 10 '10 at 14:30
  • 1
    @chicodoro, you may be thinking of the restriction that at most one may be a top-level class. Here's an example of a public class nested in another public class: http://download.oracle.com/javase/6/docs/api/java/nio/channels/Pipe.SinkChannel.html . – Andy Thomas Nov 10 '10 at 14:40
  • It's an incomplete answer, and it doesn't say that it's incomplete. You can also have inner classes, which is actually what the OP posted in his C++ code. That makes this answer poor. – Erick Robertson Nov 10 '10 at 17:30
15

It is possible to have one class inside of another class. In Java, it's called an inner class

Dave McClelland
  • 3,385
  • 1
  • 29
  • 44
  • What would be the custom here? Using an inner class for this kind of helper class or one of those package private classes? – Espen Nov 10 '10 at 14:29
  • This can be a good way to go, but be sure you won't be needing this class elsewhere first. – jon_darkstar Nov 10 '10 at 14:30
  • 1
    Inner classes are one type of nested class. There are also static nested classes. – Andy Thomas Nov 10 '10 at 14:31
  • 1
    I'm not sure there's any proper "custom" for how to solve it. I prefer separate files, but I learned Java before C++ and it's a personal preference.. If you don't need it outside the class, make it private. If you do need it outside the class, make it protected. It all comes down to what your situation dictates. – Dave McClelland Nov 10 '10 at 14:41
12

As several others have pointed out, you can have any number of non-public classes in a single file.

To answer the "why", one likely factor is that it makes your classes easy to find. If I see a reference in a program to class Foobar, I immediately know that it must either be in the same file with the current class, or it must be in a file named Foobar.java. I can check the imports to see what directory it is in.

When I work on C or C++ programs, I regularly find myself having to do Windows file searches or Linux grep's to find the source for a class.

When I write very small programs, I often put all the classes in one file. But if it's going to be more than a few thousand lines, it's much more manageable to break it out.

When I have a class that is only used by one other class, I'll often put it in the same file. Usually this means a class that just exists to temporarily hold some small bundle of data, like I need an array or list of something that requires more than one field.

Jay
  • 26,876
  • 10
  • 61
  • 112
  • 1
    The amount of time it takes to create a new file per class is tiny compared to the time savings of being able to find the code without searching. You don't have to look through several levels of #includes or try to manually parse the makefile to find which file has which class. +1 for the explanation. – Kelly S. French Nov 10 '10 at 15:14
  • I see the point of having one file for each class. However, I never had this much problem finding a class in C++. Mainly becasue I think I do proper naming and namespacing, and becasue of the nifty right-click menu in VS. Though looking through the std or external libraries would be a pain without it. When that is said, having one file each for ten or twenty three-liner classes would just be a hassle. – Espen Nov 10 '10 at 15:28
  • @Espen: Sure, it can seem silly to have to create a separate file just to hold one tiny class. But I go back to my original point: a consistent rule makes the desired source code easy to find. Modern IDEs can help, but I'm not always using an IDE to look at my code. – Jay Nov 11 '10 at 14:14
  • +1 (only) This answer actually provides reasons for why forcing what Java forces. It also gives practices! All these can put your "Java mind" in "the right context". – n611x007 Oct 24 '13 at 11:12
  • On Windows, there are nice grep-like tools, for example https://code.google.com/p/dngrep/ :) – n611x007 Oct 24 '13 at 11:13
  • Sure. It's not like a "random" assignment of classes to files would make the code impossible to manage. It just makes it harder. If this simple rule saves me a few minutes every day, that adds up. – Jay Nov 06 '13 at 21:39
7

The restriction is that you can only have one top level public class per file (you can have nested public classes though). As people have mentioned you can have inner/nested classes within that class.

Another thing which hasn't been mentioned is that you can have another top level class in the same file, as long as it is package-private (visible only within the package). A package-private class is one which is declared without an access modifier.

Here's a chapter from Effective Java (which is worth a read) on this subject. http://books.google.co.uk/books?id=ka2VUBqHiWkC&lpg=PA67&ots=yXKoLnv2TX&dq=Minimize%20the%20accessibility%20of%20classes%20and%20members&pg=PA67#v=onepage&q&f=false

Sinjo
  • 430
  • 3
  • 7
4

The rule is one top-level public class per file. Inner class, private class and some other stuff are allowed

Erick Robertson
  • 32,125
  • 13
  • 69
  • 98
Plínio Pantaleão
  • 1,229
  • 8
  • 13
3

Java allows you to create inner classes. That is, classes within another class. That's where you should put your helper classes. On the other hand, I feel your pain. Being primarily a C++ coder myself Java can sometimes feel like it forces boilerplate upon you.

wheaties
  • 35,646
  • 15
  • 94
  • 131
3

Yes, you can nest a class inside another.

Contrary to many of the answers here, there are no restrictions on public visibility.

Nested classes include:

  • Static nested classes.
  • Inner classes, which have an implicit pointer to an instance of the containing class, and are allowed to access its private parts.
  • Anonymous inner classes, which can be created within methods of the containing class, without a name. These are convenient, for example, for short event listeners.

More details are available in this Oracle tutorial.

Andy Thomas
  • 84,978
  • 11
  • 107
  • 151
2

In Java, there is no way to put two public top-level classes into the same file, but this restriction does not apply to private/inner classes. So you could have something like:

public class MyNotSoSimpleClass {
    private MySimpleClass mySimpleClass = new MySimpleClass();

    private class MySimpleClass {
        public float numbers[4];
        ...
    }
....

}

nosirrahcd
  • 1,467
  • 3
  • 18
  • 36
  • 1
    This is false. It is possible to have arbitrarily many public classes in the same source file. It's just not possible to have more than one *top-level* class in the same file. – Andy Thomas Nov 10 '10 at 14:19
  • Obviously. Thus private/inner classes. I'm not saying they are the same thing. Inner classes are, by definition *not* top level... – nosirrahcd Nov 10 '10 at 14:30
  • @Andy: Obviously, user468341 was talking about top-level classes. – chiccodoro Nov 10 '10 at 14:32
  • 2
    @user458341 - "Public" is not a synonym for "top-level." Nested classes are not required to be private. – Andy Thomas Nov 10 '10 at 14:43
  • This answer is ambiguous, it talk about many top level classes, and the example gives a one top level class with a inner class. It should give the 2 examples. – pdem Oct 31 '18 at 10:19
0

In Java there is something called nested classes, read more about it here!

dirbacke
  • 2,861
  • 21
  • 25