My question is: it's known that nested class cannot have a static member (only if the class isn't described as static). But sometimes we need to have it.
Ex: we have a library. It has books (we will consider books as the inseparable part of library, I just can't guess about another example).
In class Library I should describe nested private class Book. Nested because Book exists only in a Library(as I described before). Private because we want to permit creation book outside of the Library. I want to have counter of all books, stored in all libraries. I simple situation I should have static counter, but there I can't. And I can't describe Book as static class because Book belongs to the Library.
Your reasoning for having a nested class doesn't really make sense.
If you really want Book to only be accessible by library, you can declare it package private by putting it in a package with library and declaring the class to be private.
That way, only library can use the class.
e.g.
package com.company.library;
private class Book {
}
The reason you can't have a static member in Book is that a Book is a non-static member of Library. As such, the Book class has an implicit reference an enclosing class instance (an instance of Library). You have a number of options:
Make the Book class static.
Keep the static counter in the Library class instead.
Make Book a completely separate class from Library altogether. A library instance can keep a counter of how many books it holds.
I personally think #3 is the better option. A Book should not be forced to be in a library, it should also be allowed on a CoffeeTable. :P
If you want to have a counter of all books in all libraries, I would rather ask each library for its count of books, and total the lot.
I think this is much better handled by asking the libraries for info about what they contain. The libraries look after their books, and the responsibility lies with them. Maintaining that shared state outside the libraries breaks encapsulations (and depending on the implementation, may introduce you to pain when concurrently updating etc., if you choose to do that in the future).
Remember that one of the points of OO is to tell objects to do things for you.
I'm not sure about your assertion re. books existing only in a library. They belong to a library, but that's slightly different. Your books can be standalone objects (not necessarily inner classes), and perhaps your libraries should contain a book factory, that creates a book with a reference to the owning library. Check out the Factory pattern for more info.
Nested (non-static) classes in Java tend to be a generally confusing concept. I would recommend against using them, unless you really know what you are doing, and have a convincing need (since other people having to maintain your code will also have to understand it). Nested classes are a kind of dark corner of the language, which it is always possible to avoid.
In general, the use case for making a class nested, is when the class is only used by the outer class. For example, the Library may have a CardCatalog, which is internal to the Library, and which never interacts directly with users of the Library. Even then, it will often be less confusing, if you make the relationship between them be slightly more explicit, by making the CardCatalog a static inner class, and passing it a Library instance in its constructor. Besides everything else, it will be more testable.
I can understand the problem that you mentioned but tell me something.The mapping of Library to book is One to many. That is one Library can have many books.So in my opinion this could be handled better if you have a Separate library class and separate books class. You can have an arrayList associated with Library class of type Book eg:
Class Library { private ArrayList<.Books>; }
such kind of thing would help you to solve the problem in a better way. For keeping a count of the book have a count class that will be associated with each book instance same way as we have the Library to Books.
Is this what you mean?
class Library {
private static long allBooksInAllLibraries;
private class Book {
private Book() {
// this should be synchronized if threads are involved
allBooksInAllLibraries += 1;
}
}
}
Non-static nested lasses are really meant for cases where there is only one instance of the nested class per instance of the outer class. This is clearly not the case in your example.
Therefore you should either convert Book to a static nested class, or pull it out and create a regular class (this is the better option). You can restrict the access to it, by making it protected or package private (by just defining it with class Book).
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I was reading Thinking in Java, about why inner classes exist and what problem they help solve.
The most compelling reason the book tries to give is:
Each inner class can independently inherit from an implementation.
Thus, the inner class is not limited by whether the outer class is
already inheriting from an implementation.
Please help review my understanding:
Inner classes exist since Java doesn't support Multiple Inheritance. This (multiple inheritances) can be done within an Inner class which it is that the Outer class can have multiple inner classes, and each of them can inherit from different classes. So in this way, The multiple inheritances can be implemented. Another reason I can think of is Inner classes address the OOP design principle composition better than inheritance.
Updated
Most of the explanation I found just like the answers below. for example, Inner class used in the GUI framework to deal with the event handler. Not mentioned the reason quoted in the book.I am not saying the answers below are not the good. Actually. I really appreciated them(+1). I just want to know Is there something problem with the book?
It is a little puzzling why you thought of the idea of multiple inheritance after reading the most compelling reason you have quoted from the book. Multiple inheritance comes into question when a class (inner or not) wants to inherit behavior from more than one concrete implementation. Thus, unlike some other languages, in Java, you can not define a class like:
class Child extends Father, Mother {
// Child wants to inherit some behavior from Father and some from Mother
}
As you can see, nothing that only inner classes do can rectify or work around this Java decision (not to support multiple inheritance) in a straightforward way.
Then why do they exist, you may wonder! Well, in Java every class is either top-level or inner (also called nested). Any class that is defined inside another class is an inner class and any class that isn't so is a top-level class.
Naturally, one might wonder why to define classes (i.e. behavior) inside other classes. Aren't top-level classes enough?
The answer is yes. Java could always have only top-level classes. But the idea (perhaps) was there was no good reason to restrict classes from being members of other classes! Just like any predefined type (e.g. Integer, String etc.) can be a member of a class:
class Person {
private String name; // a field the models a Person's name
}
a programmer should be able to define a behavior of one's interest inside the class:
class Person {
private String name; // a field the models a Person's name
private Address address; // address is a type defined here
static class Address {
String street;
String city;
}
}
There's a lot going on here, especially with these things like private, static etc. which are called the modifiers. There are many technical details about them, but let us come back to them later. The essential idea is to be able to define behavior as a part of another class. Could the Address class be defined outside Person class, as a top-level class? Of course. But having this facility comes in handy.
Now, since this facility was introduced, it started serving another purpose and that purpose is called providing code as data. This is how design patterns emerge and it was thought until about 10 years ago that inner classes can be used to provide the data in the form of code. Perhaps this is somewhat puzzling to you. Consider the following code that I have taken almost verbatim from the JDK class: java.lang.String.java:
public static final Comparator<String> CASE_INSENSITIVE_ORDER
= new CaseInsensitiveComparator();
private static class CaseInsensitiveComparator
implements Comparator<String> {
public int compare(String s1, String s2) {
int n1 = s1.length();
int n2 = s2.length();
// details excluded for brevity
// return -1, 0, 1 appropriately
}
}
What has happened here?
We need a way to compare a String to another String and we need to be able to do a case-insensitive comparison. So, we created an implementation of the Comparator interface right inside the outer class: String! Isn't this handy? If inner class wouldn't be there, this would have to be:
public class String {
// ... the whole String class implementation
}
class CaseInsensitiveComparator
implements Comparator<String> {
// implements the comparator method
}
and that's not 'bad' per se, but it means a lot of classes polluting the name space. Inner classes restrict the scope of a behavior to the outer class. That comes in handy, as you'd perhaps see. The data in this case is the implementation of the Comparator interface and the code is well, the same, because we are _new_ing up the inner class we defined.
This feature was exploited further using the anonymous inner classes (especially in the cases where you wanted the code to serve as data) up until Java 7 and they were effectively replaced by Lambda Expressions in Java 8. Nowadays, you might not see any new code that uses anonymous inner classes (in other words, language evolves).
Why Use Nested Classes?
Compelling reasons for using nested classes include the following:
It is a way of logically grouping classes that are only used in one
place: If a class is useful to only one other class, then it is
logical to embed it in that class and keep the two together. Nesting
such "helper classes" makes their package more streamlined.
It increases encapsulation: Consider two top-level classes, A and B,
where B needs access to members of A that would otherwise be declared
private. By hiding class B within class A, A's members can be declared
private and B can access them. In addition, B itself can be hidden
from the outside world.
It can lead to more readable and maintainable code: Nesting small
classes within top-level classes places the code closer to where it is
used.
Oracle Documentation: Understanding inner classes
Below SO question might be interesting to you -
What is the reason for making a nested class static in HashMap or LinkedList?
UPDATE
Not mentioned the reason quoted in the book. ... I just want to know
Is there something problem with the book?
I don't think there is any problem with the statement you have highlighted.
Each inner class can independently inherit from an implementation: That's true right. Just like an outer class, it can inherit from an implementation independently. Just think both of them as separate class.
Thus, the inner class is not limited by whether the outer class is already inheriting from an implementation: As both are separate class, it doesn't matter whether outer class is already inheriting from an implementation. Inner class can inherit from an implementation too. After all it's a class too.
If you are looking for use-cases, I can only tell you what I use them for frequently, which are basically these 2 things:
Static inner classes I use for helping to implement some internal logic. These are usually some form of tuples, or some simple containers. For example: Maps have "Entries" in them which are basically just pairs.
Representing runtime parent-child relationships. These are non-static inner classes. For example: I have a Job class which may instantiate multiple Task inner classes that need to see the data in the job for their processing.
There may be more use-cases of course...
By making private constructor, we can avoid instantiating class from anywhere outside. and by making class final, no other class can extend it. Why is it necessary for Util class to have private constructor and final class ?
This is not a mandate from a functional point of view or java complication or runtime. However, it's a coding standard accepted by the wider community. Even most static code review tools, like checkstyle, check that such classes have this convention followed.
Why this convention is followed is already explained in other answers and even OP covered that, but I'd like to explain it a little further.
Mostly utility classes are a collection of methods/functions which are independent of an object instance. Those are kind of like aggregate functions as they depend only on parameters for return values and are not associated with class variables of the utility class. So, these functions/methods are mostly kept static. As a result, utility classes are, ideally, classes with only static methods. Therefore, any programmer calling these methods doesn't need to instantiate the class. However, some robo-coders (maybe with less experience or interest) will tend to create the object as they believe they need to before calling its method. To avoid that, we have 3 options:
Keep educating people to not instantiate it. (No sane person can keep doing it.)
Mark the utility class as abstract: Now robo-coders will not create the object. However, reviewers and the wider java community will argue that marking the class as abstract means you want someone to extend it. So, this is also not a good option.
Private constructor: Not protected because it'll allow a child class to instantiate the object.
Now, if someone wants to add a new method for some functionality to the utility class, they don't need to extend it: they can add a new method as each method is independent and has no chance of breaking other functionalities. So, no need to override it. Also, you are not going to instantiate it, so no need to subclass it. Better to mark it final.
In summary, instantiating a utility class (new MyUtilityClass()) does not make sense. Hence the constructors should be private. And you never want to override or extend it, so mark it final.
It's not necessary, but it is convenient. A utility class is just a namespace holder of related functions and is not meant to be instantiated or subclassed. So preventing instantiation and extension sends a correct message to the user of the class.
There is an important distinction between the Java Language, and the Java Runtime.
When the java class is compiled to bytecode, there is no concept of access restriction, public, package, protected, private are equivalent. It is always possible via reflection or bytecode manipulation to invoke the private constructor, so the jvm cannot rely on that ability.
final on the other hand, is something that persists through to the bytecode, and the guarantees it provides can be used by javac to generate more efficient bytecode, and by the jvm to generate more efficient machine instructions.
Most of the optimisations this enabled are no longer relevant, as the jvm now applies the same optimisations to all classes that are monomorphic at runtime—and these were always the most important.
By default this kind of class normally is used to aggregate functions who do different this, in that case we didn't need to create a new object
I have a question regarding UML. I have a class which simply contains an inner class with the private access modifier - cannot be accessed from anywhere else... Normally in order to present an inner class relation I can use a (+) relation like here (InnerOddIterator):
(taken from http://www.uml-diagrams.org/nested-classifier.html)
I have not found anywhere any information about how can clearly emphasize that this class is private. Do you know if such a method exist at all? If yes I'll be grateful you give me some link here or something?
Just to keep things clear, a sample code:
public class DataStrucure {
// fields, methods, etc
private class InnerOddIterator{
// ...
};
}
From UML point of view. If classifier (Class also) is nested in other class, nesting class plays role of namespace. In this case nested classes are hidden (private) in context namespace. it means, your diagram implicitly defines private inner class definition.
here is part of definition from UML Superstructure section structred classifiers:
"A class acts as the namespace for various kinds of classifiers defined within its scope, including classes. Nesting of
classifiers limits the visibility of the classifier to within the scope of the namespace of the containing class and is used for
reasons of information hiding. Nested classifiers are used like any other classifier in the containing class."
First of all: You have something in your code and asking for an UML representation. But, IMHO, you should look at it the other way round: How can that UML-idea be represented in code. (Some programming languages don't even offer private nested classes...).
As for private nested classes: I suggest using a Composition. It is stronger as Association but not as strong as inheritance. And the composed class can not exist without its composer. Pretty much exactly a private nested class.
The drawing is taken from http://www.uml-diagrams.org/association.html:
In order to indicate that your inner class is privete the best, for me, is to use - character as depicted below but of course in this case you miss the internal structure of your inner class..
I'm 14 and have been learning java for about 4/5 months. I'm coding a game now called super mario winshine and i wanted to know if it is good practice to have a class that is mostly static variables.
The class is the one that holds all the information for the game's level/world. Since I only need one version of this class, and lots of other classes will be using it, I choose to make all the variables static. Is this good practice?
I have considered the fact that i could keep the variables "non-static" and just clone the main object i use for that class, but I thought i would rather sacrifice "O-O" for memory in this case.
As soon as you want to have two or more worlds this will fail. Say, when your first release is a runaway success and you want to add the "parallel universe" expansion set.
In my experience, 90% of the time when marketing says "oh, don't worry, there will only be one Application/Window/Database/User" they are wrong.
ADDED
I would also avoid using a true Singleton pattern with World.getInstance() etc. Those are for the rare cases where it really is an essential requirement that there only be one of something. In your case, you are using it as a convenience, not a requirement.
There is no perfect fix, YMMV, but I'd consider a single static method, something like
World World.getWorld(String name)
and then you call real (non-static) methods on the World that is returned. For V1 of your program, allow null to mean "the default world".
Some might put that method into a class named WorldManager, or, perhaps showing my age, a more clever name like Amber. :-)
It all depends upon what your methods and classes are. There is no problem in defining utility methods as static methods in a class. There is no need to make it a singleton as others are suggesting. Look at the Math class from java.lang package. It has lot of utility methods but it isn't a singleton.
Also check out static imports functionality. Using this you doesn't need to qualify method calls with the class name.
Well, what you are doing is definitely an option. Or you could use a singleton pattern:
public class World {
private static World instance = new World();
private World() {
}
public static World getInstance() {
return instance;
}
}
Now just use World.getInstance() everywhere to have a unique object of this type per application.
I would say it's definitely not a good practice.
I've not seen your code, but having several static variables in a class that other classes access freely seems to indicate that you're not really using object orientation/classes but more just writing procedural code in Java. Classes should generally encapsulate/hide all their variables - static or not - from access from other classes so that other classes don't depend on how the class is implemented.
The static part also causes problems with making threads work (global variables are hard to lock in a good way so that nothing deadlocks) and with unit testing (mocking is all but impossible)
I also agree with the other posters, if you need "global variables", at least make them singletons. That allows you to change strategy easier later and does not lock you to one world.
Edit: I'm definitely not advocating singletons as a good pattern here if someone read it like that, but it does solve some problems with static variables, esp. regarding testing/mocking compared to just statics so I'd say it's a ever so slightly lighter shade of gray :) It is also a pattern that is easier to gradually replace with better patterns by for example using a IoC container.
I think it is fine as long as you don't need anything more sophisticated, in other words, static fields are OK as long as different objects (including subclasses if there will be any) do not need different values.
You code by yourself, refactoring is easy with modern tools, me says don't fix it until it is broken, and focus on the algorithmic aspects of your project.
Perhaps you may think to encapsulate all those static fields within a different static class, as it is a good principle to "keep what changes seperate from what does not". Chances are one day you will want to initiate that static class with different values, for example want to read the initial values from an XML file and/or registry, add behaviour, etc. so instead of a static class you will implement it with a Singleton pattern.
But clearly that is not the concern of today. Till then, enjoy!
You may wish to look into implementing this class as a singleton, while there is nothing particularly wrong with your approach it may lead to some inflexibility further down the road.
Also you should take in to consideration the purpose of static members which is to be a member of the class and 'act' on/with the class not an instance of it. For example the static method in a singleton returns either a new instance of the class if one doesn't already exist or returns the instance, and because the method is static you do not instantiate a new one. This is probably worth a read because it can be somewhat confusing when determining the appropriate use of static members
I'm not sure what you are really talking about from your short description, so I'll try this:
public class Level {
static List<Mushroom> mushrooms;
static List<Coin> coins;
...
}
Is that you were describing?
You asked if this is "good practice" and I can tell you that this looks very odd, so, no, it's not.
You gain absolutely nothing by doing this. You make it impossible to have more than one Level, which brings no advantage, but it could cause trouble in the future.
I didn't understand your last paragraph where you say you made most things static to save memory. You would usually create one Level and it would be passed around (without cloning) to the various classes/methods that read from it or modify it.
First this IS a Java question so forgive this first C#-related explanation...
I've most recently been using C# where one .cs source file can contain multiple class definitions, example...
// Servers.cs
public class Server {
}
public class ServerList : ArrayList <Server> {
}
I do the above because it reduces the number of source files and keeps the two classes together.
In Java of course it's one class to one .java file but I had the idea of nesting the Server class as follows...
//Servers.java
public class ServerList extends ArrayList<ServerList.Server> {
// Edited to make Server class 'static'
public static class Server implements Serializable {
}
}
This builds without compile time errors or warnings but I can't decide if it's right.
The more I look at it, the more I'm happier with it but I'm still worried that it may be considered bad practice or I could run into problems along the line.
So the question...is this OK to do? Sorry if this is a rookie Java question (or even a rookie OOP question - despite using OOP going back to mid 1990s with C++, I'm self taught and have never tried something like this).
EDIT:
Many thanks to all who have provided comments/pointers to this question.
Firstly I've edited my code to make the Server class static - I expect I would have discovered this down the line but it's good to know from the start that I should be approaching it this way.
To expand on things related to other comments...
I have reasons for extending ArrayList rather than using ArrayList (or List) in associated code. I didn't include the code (haven't started yet) but ServerList will encapsulate specific handling of Server objects (including searching on Server-specific fields/members).
Also I'm using ArrayList rather than List as I'll be using an instance of ServerList to bind to an Android Spinner widget (nice and easy with an ArrayAdapter). Sorry I didn't mention Android but my question was (in my mind) specific to Java practice and not really to my choice of classes to achieve what I'm looking to do.
As for extensibility / inheritance etc with respect to other programmers (or myself) using the Server or ServerList classes at a later date, they really are quite specific to the requirements of my current project...not necessarily a good OO approach to class definition I admit (and not usually my approach) but they serve my project best in terms of usability and efficiency.
Thanks again to all.
If you want to mirror your first example more closely, you should make your inner class static:
public class ServerList extends ArrayList<ServerList.Server> {
public class static Server implements Serializable {
}
}
That means that the inner class can be created independently and is not related to the outer class. Otherwise, each inner class would be linked to its outer class (and would have access to those class' members as well) and would therefore be required to be created from within the context of ServerList.
I have two issues with this:
since Server is the important class here, it should be a top level class. Having it as an inner class IMHO makes your code unintuitive, harder to understand. (And as #EboMike pointed out, whichever way you do it, the inner class should be static.)
I don't see a good reason to subclass ArrayList<Server> - apart from creating an extra class of minimal use, this ties its implementation to ArrayList, which limits your future options. I would prefer declaring List<Server> on public interfaces - program to interfaces, not to implementations. It is just as readable as ServerList, and more usable, since any Java programmer will know what it is, and how to use it.
I can be perfectly fine to nest classes. Try searching google for nested classes:
http://www.javaworld.com/javaworld/javatips/jw-javatip75.html
That is a good article on it. But to answer the question, no it is not "bad practice" but there are specific times you will use it.
It is technical perfect legal do do this, if you have a good reason.
For example the Java Map Interface do something (not 100%) similar: It has an Inner Interface Map.Entity, and defined an entry set, that uses this Inner Interface (Set<Map.Entry<K, V>> entrySet()) .
Anyway, you should make the inner class static, if you do not need access to the outer class within the inner one.