In Java a nested class is an inner class that is declared static. E.g.:
class Basic{
public static class NestedClass{};
}
I am wondering if a nested class is a singleton by default, or if I may create a list of instances such as
class Basic{
public static NestedClass{};
List<NestedClass> items;
}
No, it's not a singleton (where did you get that idea?). Apart from the fact that it's a static nested class (and that does not imply that it's a singleton), it's a normal class as any other - in particular, you can create as many different instances of NestedClass as you want. If you need it to be a singleton, then you'll have to explicitly code it yourself.
In Java a nested class is an inner class that is declared static.
No. In Java an inner class is a nested class that is not explicitly or implicitly declared static. JLS #8.1.3. You have this back to front.
I am wondering if a nested class is a singleton by default
No.
Nesting, static, and inner have nothing to do with singletons.
Related
All variables inside of interface are public static and final.
So if I declare a nested class inside an interface will it also become static and final?
Interface I
{
class c
{
static void m(){ }
}
}
Lets find out. Lets create structure like:
interface Interface{
class Foo{}
}
Now we can test:
System.out.println("static: " + Modifier.isStatic(Interface.Foo.class.getModifiers()));
System.out.println("final: " + Modifier.isFinal(Interface.Foo.class.getModifiers()));
which prints:
static: true
final: false
So nested classes are implicitly static, but not final.
We can confirm it also by adding class Bar extends Foo{} to our interface. final classes can't be extended but since such code compiles fine it means Foo is not final.
Classes nested inside interfaces behave like static classes nested inside classes, in the sense that you do not need to have an instance of an outer class in order to construct an instance of a nested class. According to Java Language Specification, §8.1.3:
8.1.3 Inner Classes and Enclosing Instances
[...] A member class of an interface is implicitly static (§9.5) so is never considered to be an inner class.
However, these classes are not final, unless you explicitly designate them as such. This makes sense, because classes that implement an interface may need an opportunity to extend nested classes defined inside the interface.
I know the meaning of nested static classes, but found it confusing sometimes deciding when to declare them over non static nested classes.
Is it mainly when instantiation wouldn't be a good sense?
What are the general rules of thumb helping you decide when to use static modifier?
This is a very interesting question. I would try to explain it to you.
A nested class is a member of its enclosing class. Non-static nested
classes (inner classes) have access to other members of the enclosing
class, even if they are declared private. Static nested classes do not
have access to other members of the enclosing class.
Basically, a static nested class interacts with the instance members of its top-level class, just like any other classes.
So, basically you can and should consider a static nested class as a top-level class which has been nested inside another top-level class just for packaging convenience.
So whenever you are using a nested class, start by making it static, and then see if you need to access any instance members thereby having an opportunity to make it non-static.
Take the example from JDK,
public class LinkedList<E> ... {
...
private static class Entry<E> { ... }
}
Here, the Entry is a static nested class as it doesn't make any sense for this class to be a top-level class as it is used by the LinkedList class only. And since it doesn't even use any members of the LinkedList class, thus making is static makes even more sense.
always use static. if you need to access members from the outer class use non static
Edit: a good explanation can be found here https://sonar.spring.io/coding_rules#rule_key=squid%3AS2694|s=createdAt|asc=false
You should use the static field, method or class when ever you can and the code still compiles and works correctly.
If the code wouldn't compile or not work if you made it static, don't make it static.
You'd use a static class when you don't want the class to access non-static (or instance) fields of the top-level class and the top-level class doesn't need an instance of it.
Always use a static inner class unless you can't use a non-static class. This keeps the code simpler and it's more memory efficient.
The Java Tutorial says that the static nested classes are accessed by using the name of the enclosing class like new EnclosingClassNameHere.StaticNestedClassNameHere()
Why would i want to create an instance of a static class at all? Can somebody please explain?
"static" in this case can be misleading. What it really means is that the class can exist independently. Non-static inner classes can't exist without an instance of the enclosing class.
IMO, when you start using an inner class outside the class that it's in, you need to consider moving it and making it its own top level class. There are very few cases where the relationship between the classes is so tightly coupled that you need to keep it as an inner class.
In your code example:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
You're creating a stand-alone instance of StaticNestedClass.
If it wasn't static, you couldn't do that. You could only create instances of StaticNestedClass() from an instance of OuterClass.
If you moved it to its own .java file, you could treat it nearly identically:
StaticNestedClass notNestedAnymore = new StaticNestedClass();
As to your real question: Why would you want to create an instance of it? For the same reason that you create instances of any class - it does some piece of work that you need.
There is nothing confusing with this code. Static nested class is just a way to introduce yet another namespace.
By creating a static nested class you express very strong relationship between outer and inner class. Typically nested class is a helper or a part of the outer class. For instance when you create a Tree class, Node class is a good candidate for a nested static class. The Tree.Node clearly explains the purpose of the Node class.
In fact, static keyword usage is consistent with static fields. In both cases you can access static entity without an instance of enclosing class. When it comes to static classes it basically means: "I can create an instance of this static nested class without having an instance of outer class". By default (when static keyword is not used) the nested class becomes inner class. In this case you cannot simply write:
new OuterClass.StaticNestedClass();
Instead you are required to pass OuterClass instance with a bit obscure syntax:
OuterClass outerClassInstance = new OuterClass();
outerClassInstance.new InnerClass();
Fortunately when new InnerClass() is executed inside an OuterClass body, this is implictly used as enclosing instance.
In java inner classes have an implicit reference to an instance of the outer class. This way you can access members of the outer class directly, which is usefull in annonymous classes used for callbacks.
class A{
private int a = 3;
class Inner{
Inner(){
System.out.println(a);//also A.this.a
}
}
static class StaticInner{
StaticInner(){
System.out.println(a);//FAILS
}
}
}
Declaring an inner class static simply removes this implicit reference and that is the only difference between static and non static inner classes.
Why can't a java nested Interface be non-static ? And why can't an inner class contain static non final members ?
I came across the questions while going through Gosling and haven't been able to figure out the answer yet.
If an nested class is non-static (i.e. an inner class), this means that each instance of it is bound to an instance of the outer class. As an interface has no instances of its own, it seems to not be useful for the implementing classes to be bound to an outer object, so having it static by default seems reasonable.
I'm not sure why you can't have static non final members in an inner class but since static members aren't bound to any particular object instance it makes no difference whether it is in the inner or outer class.
E.g.
class OuterClass {
private static int staticMember;
class InnerClass {
void incStatic() {
staticMember++;
}
}
}
You can access the static member from the inner class as if it were within the inner class.
I'm new to Java and have the following question regarding inner classes:
When implementing an inner class, do I need to declare its attributes and methods scope i.e. public, private, protected?
EDIT: With the absence of delegates (as in C#) could someone mention how best to implement a messaging system in Java that enables communication between multiple forms (Jframe)?
I have read that I can use inner classes for this but I'm also told I should not implement inner classes more than a few lines in size. Which school should I follow?
If you want to.
An inner class is roughly speaking like any other class. (Except that if you don't declare it static, it will have an EnclosingClass.this reference.)
I would suggest treating inner classes as private.
In Java, an outer class and all of its nested (including inner) classes can fiddle with each others privates. (The generated bytecode may be pointlessly verbose with additional synthetic access methods, but this is highly unlikely to matter.)
From an interface point of view, a class having weird inner class types is a bit weird. And more difficult to test if you are into that sort of thing. Too often nested type are created because creating a new file in a bad IDE is a bit of a pain - don't be tempted with nasty shortcuts.
Having said that inner classes are very useful. Use them with taste.
when implementing a inner class do i need to declare its attributes and methods scope i.e. public, private, protected?
It depends completely on how you wanted the inner class to behave.
By default, an inner class is non-static:
public class Example1
{
int a;
public class Example2
{
int b;
void test () {}
}
}
A non-static inner class can be instantiated only inside a non-static method of the outer class. This is because every instance of a non-static inner class must be associated with an instance of the outer class. In a sense, every instance of a non-static inner class exists ``inside'' an instance of the outer class. A single instance of the outer class may have associated with it more than one instance of the inner class.
Because an instance of a non-static inner class has an associated instance of the outer class, the methods of the inner class can access directly any of the members (fields or methods) of the outer class instance. For example, the test method defined above can access both a and b directly
A class defined within another class is called a nested class. Like other members of a class, a nested class can be declared static or not. A nonstatic nested class is called an inner class. An instance of an inner class can exist only within an instance of its enclosing class and has access to its enclosing class's members even if they are declared private.
The following table shows the types of nested classes:
Types of Nested Classes Type Scope Inner
static nested class member no
inner [non-static] class member yes
local class local yes
anonymous class only the point
where it is
defined yes
Although this is not an answer your question but make sure you are aware of the "static" modifier of inner classes.
public class Stuff {
public static class SubStuff {
//private or protected
}
}
Is different than this:
public class Stuff {
public class SubStuff {
//only private
}
}
If you have a static inner class than you might want protected variables, protected methods so on. But for inner classes that are not static generally you want everything private.
Google for the difference.
Inner can be seen by only the enclosing class. Its mostly used to achieve a utility function within the class. Lets use Door and Password as example.
public class Door {
public boolean isPassword(String key) {
//local inner class - its hidden from the world
class Password{
public boolean isPassword(String key) {
if(!key.equals("xyz")) {
System.out.println("Not Password. Door is locked");
return false;
}else {
System.out.println("Password corect. Door is opened");
return true;
}
}
}
return new Password().isPassword(key);
}
}