Are nested classes inside an interface implicitly static and final? - java

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.

Related

Inner classes inheritance and access to enclosing class methods/fields

Here are two statements I found concerning inner classes
JavaDocs:
As with instance methods and variables, an inner class is associated
with an instance of its enclosing class and has direct access to that
object's methods and fields. Also, because an inner class is
associated with an instance, it cannot define any static members
itself.
On another site I found this:
A nested class, for the most part, is just that—a class declared in
the definition of an enclosing class. It does not inherit anything
from the enclosing class, and an instance of the nested class cannot
be assigned to a variable reference to the enclosing class.
Aren't the bold marked lines contradicting?
How can you not inherit a surrounding objects fields and methods and at the same time have access to its fields and methods?
No, they do not conflict. Look at the following example:
public class A {
public void foo() {
//some code
}
public class B {
public void bar() {
foo();
}
}
}
In this example, the innerclass B can access the method of A (or any of its' fields, actually), but in no way does inheritance takes place.
For instance, the following change to B would result in a compilation error:
public class B {
public void bar() {
super.foo();
}
}
Because B does not inherit from A. It can access its' instance members, but it does not extend (inherit) from it.
Please do not see the terms nested class and inner class as an opposite or something similar. In fact, a nested class simply describes all sorts of classes that are declared inside another class:
Nested classes that are declared static are simply called static nested classes.
Non-static nested classes are called inner classes. There are three types of them (see JLS §8.1.3 for more info):
A non-static member class.
A local class.
An anonymous class.
The first paragraph you quoted explains that an inner class has access (read: access, not inherit) to the methods and fields of the enclosing instance. Note, it is about an instance, not the class.
The second paragraph tries to explain that there is no relationship between a class and a nested class inside it, except for their locations.

Compiler Error when Interface within Inner Class

I want to declare an interface inside an inner class, which shows compiler error message "inner classes cannot have static declarations".
public class Apple {
//...
public class InnerApple{
//...
public interface InnerInterface{
//Error: inner classes cannot have static declarations
}
}
}
Does it mean interface is actually static in Java?
I'm using Java 1.7. Thanks!!
An interface is always static - in a sense that there cannot be any dependency to another instance.
Having two levels of inner declarations is quite uncommon, but if it is intended I would expect that at least InnerApple is static:
public class Apple {
public static class InnerApple{
public interface InnerInterface{
//this does not cause an error
}
}
}
In most cases the keyword static of inner classes is omitted. If so this class may contain dependencies to a surrounding instance (and not only to the class as static inner classes do).
Yes, member interfaces are implicitly static. Section 8.5.1 of the JLS states:
A member interface is implicitly static (§9.1.1).
For it not to be static, the interface must be top-level, with no enclosing class or interface.

is a nested class a singleton in java

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.

Why interface can only be declared in top-level class?

Alright, I know it's the rule:
According to JLS: 8.1.3 Inner Classes and Enclosing Instances, inner
classes may not declare static initializers or member interfaces.
Inner classes may not declare static members, unless they are
compile-time constant fields.
According to 8.5.2 Static Member Type Declarations, "Member interfaces
are always implicitly static. It is permitted but not required for the
declaration of a member interface to explicitly list the static
modifier". They are always top-level, not inner.
I just wonder why. What may happen if we are allowed to declare interface within an inner class? Won't inner class become top-level class if I put it into another Class file?
Won't inner class become top-level class if I put it into another Class file?
No, it still is an inner class, which the filename indicates (IIRC it's OuterClass$InnerClass.class).
Inner classes have access to the outer class' attributes, i.e. they depend on their outer class' instance. With interfaces you couldn't do this. Think of a completely unrelated class that would have to be created by the corresponding outer class' instance. How would that be done if the outer class doesn't know who implements that interface?
What you can do is declare static interfaces in your outer class, thus merely using the outer as a namespace:
public class OuterClass {
public static interface InnerInterface { //protected and private would be fine too, depending on what makes sense
}
}
Edit: actually, I misread the question and since interfaces are static anyways, here's an updated code snippet:
public class OuterClass {
public static InnerClass { //static inner class making OuterClass just be a namespace
public interface InnerInnerInterface { //protected and private would be fine too, depending on what makes sense
}
}
}
As a workaround you could define an abstract inner inner class, with the drawback that you have to stick to the single inheritance constraint.
Think of it in terms of static vs. non-static context. A "top-level" class establishes a static context because it can be accessed without any enclosing instance. I.e. you can access top-level classes from a main method. The same applies to any static members of a top-level class. An inner class, however, neither exists in* nor establishes any static context. Therefore it can't have any static members, and it can only be accessed via an instance of its containing class, like constructors and other instance members. From a main method, you wouldn't be able to say Outer.Inner.SOME_FIELD because members of an inner class only have meaning with respect to the containing class.
*sort of
By definition a top level class and its inner class(es) are tightly coupled. Interfaces are a means of reducing coupling.
Inner classes are supposed to be implementation details of the top-level class and should therefore be invisible to the client. Any functionality you wish to access of an inner class should be done so through the top-level class, because conceptually speaking, that functionality should be visible only as functionality of the top-level class, so that the class designer can swap out or otherwise drastically change inner classes without breaking clients' builds.

Java Inner Classes

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);
}
}

Categories