In Java, if a nested class is not declared as static, it cannot be accessed within a static context. This means an instance of the inner class can only be created through an instance of the outer class. For example:
class Prac{
class Inner{}
public static void main(){
Inner myObj = new Prac().new Inner();
}
}
For my Java-adjusted brain, this makes sense. If an inner class isn't static, it would require an instance of the outer class to be instantiated from. In c# however, I can declare Inner non-statically as a nested class and directly instantiate it from a static context in the Main method.
I read that c# nested classes are like c++ and not java, but I'm not familiar with how inner classes work in any other way. What are the mechanics underlying nested classes in c#?
Consider that Microsoft strongly suggests to avoid public nested classes.
The core idea of a nested class is to completely hide to everyone an implementation detail of an abstraction. Consider that example:
IUserService
public interface IUserService
{
IEnumerable<string> GetAllUsernames();
}
MockUserServiceProvider
public static class MockUserServiceProvider
{
// Public
public static IUserService New() => new MockUserService();
// Nested Private class
private class MockUserService : IUserService
{
public IEnumerable<string> GetAllUsernames()
{
yield return "Bob";
yield return "Mary";
}
}
}
The goal of the Mock provider is to make available to the public an instance of the interface to Mock, it does not make sense to bind the provider to a specific class type, indeed, in theory, that type just shouldn't exist at all. So the best one can do (Without use some I.L. magic as Moq does for example) is to completely hide the class definition with a private nested class, so that no one can access it.
Related
Since an enclosing class can access the private fields of its inner class, when should be they declared private, default or public for a private inner class?
At first glance, it seems irrelevant to specify an access modifier on the members of inner classes. As you pointed out, the containing class can access all members anyway.
Here are a few additional considerations though:
Sometimes inner classes are declared public and serve as part of the interface definition of the containing class. Perhaps the outer class has a method that returns an instance of the inner class. In this case, the inner class is subject to the same best practices for member visibility as top-level classes. It's preferrable to keep implementation details private in this case.
Although it wouldn't be enforced by the compiler, marking an inner class's members as private can document for future maintainers that those members are not intended to be accessed directly by the outer class code. Of course, at that point, it might warrant refactoring the inner class to its own top-level class.
Sometimes inner classes are used in combination with reflection-based frameworks that only operate on public members. For example, the Jackson JSON serializer by default only operates on public members. It is possible to make it operate on private members by doing a few things like adding a public getter. This is extra work, so it may be more convenient to declare the member public in the first place.
If the above points do not apply, and in the absence of any other requirements, the simplest and shortest code is to omit the access modifier entirely (default/package-private). This would be a coding style question for a project to consider.
It's a good style to declare everything private unless there is a reason to use package private or public visibility. And this reason should not be it's more convenient.
Everything that is not private may be used outside of your class and thus changes to any non-private aspect of your code may break other code places or even external code that relies on your code. Making more difficult or sometimes even impossible to do refactorings and change the inner workings of your classes.
In the special case of a private inner class everything is only visible to your containing class. That is the visibility of the inner classes' members is not of importance. To the other extreme, if you are working on a library its common practice to only expose interfaces as contract. Keeping the implementation details completely hidden.
Not only the outer class but also other classes can access inner class and its members .So when you want to make the inner class members accessible by only its outer class you can declare them as private . consider the fallowing example
There are 2 classes in same package com.exercise.test and classes in it are OtherClass and SampleClassWithInner which contains inner class InnerClass
the members of InnerClass declared as private is not accessible in OtherClass. Where as it is accessible in SampleClassWithInner
refer this code for more clarity
package com.exercise.test;
//import com.exercise.test.SampleClassWithInner.InnerClass;
public class OtherClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
SampleClassWithInner sampleobj = new SampleClassWithInner();
SampleClassWithInner.InnerClass innerobj = sampleobj.new InnerClass();
// innerobj.var1=5; //compile time error
innerobj.setVar1(5); // ok works
// System.out.println("value of inner variable declared in other
// class"+innerobj.var1);// compile time error
System.out.println("value of inner variable declared in other class "
+ innerobj.getVar1());
sampleobj.innerMethodDemo();
}
}
and
package com.exercise.test;
public class SampleClassWithInner {
class InnerClass {
private int var1;
private int var2;
public int getVar1() {
return var1;
}
public void setVar1(int var1) {
this.var1 = var1;
}
public int getVar2() {
return var2;
}
public void setVar2(int var2) {
this.var2 = var2;
}
}
public void innerMethodDemo() {
InnerClass obj = new InnerClass();
obj.var1 = 10;
System.out.println("this is form the method in outer class " +
obj.var1);
}
}
I was learning about Nested and Inner classes and this led me to think whether it is possible to extend an Inner class to be a Nested class or not. For example.
public class Outer{
public class Inner{
// notice the lack of static keyword
}
}
public class ExtendedOuter extends Outer{
public static class ExtendedInner extends Inner{
// notice the static keyword
}
}
I did try to compile the code above and I couldn't, but the compile time error I received made me believe that there may be a work around. I can however extend a Nested class to be an Inner class.
This is the compile time error I received.
no enclosing instance of type Outer is in scope
An inner class has a reference to the outer class. You cannot remove it in a subclass. This would be like removing a field in a sub-class.
Actually you can extend the inner class. You just have to provide an instance of Outer that the class will be bound to. To do so, you have to explicitly call the super constructor with the instance.
public class Outer {
public class Inner{
// notice the lack of static keyword
}
}
public class ExtendedOuter extends Outer {
private static Outer outer = new ExtendedOuter(); // or any other instance
public static class ExtendedInner extends Inner {
public ExtendedInner() {
outer.super(); // this call is explicitly required
}
}
}
This also works if you have a nested class that extends another nested class from a different enclosing class.
Your question doesn't make sense. An inner class is already a nested class, and so is any other class defined inside another one. Evidently you don't know what these words mean:
nested class: a class declared inside another one
inner class: a nested class that isn't declared 'static'.
Note that 'static nested' and 'inner' are mutually exclusive. Note also that an inner class can extend a static nested class, but not vice versa.
What your code is actually trying to do is extend the inner class as a static class, which is what causes the error. Not because the extending class is nested.
If I have class with a nested class, why wouldn't you want it to be static? Is there even a way for two instances of the same class to have different nested classes?
For example:
class MyClass {
public static class myInnerClass {
}
}
why wouldn't you want it to be static
Because I want it to access instance data of a parent object.
Is there even a way for two instances of the same class to have different nested classes?
What do you mean by have? Declared? A class has only one declaration where you list all nested classes. So, in this case the answer is no.
Take for example a Comparator or Runnable (multi-threading) implementations. This is a classic example when you need an extra class that has access to the current instance's fields and methods but is of no use outside of that class. However, static classes could be useful outside the enclosing type, too.
public class EnclosingType
{
private static final class StaticRunnableImplementation implements Runnable
{
private final EnclosingType instance;
public StaticRunnableImplementation(EnclosingType instance)
{
this.instance = instance;
}
#Override
public void run()
{
instance.getSomething();
//getSomething() leads to compile error
}
}
public class NonStaticRunnableImplementation implements Runnable
{
#Override
public void run()
{
doStuff();
}
}
public int getSomething()
{
return 42;
}
public synchronized void doStuff()
{
;
}
public void doSomething()
{
Thread t1 = new Thread(new StaticRunnableImplementation(this));
Thread t2 = new Thread(new NonStaticRunnableImplementation());
t1.start();
t2.start();
}
}
The access to the non-static methods and fields of current instance of the enclosing type, wouldn't be possible if the nested classes would be declared static.
I don't know if I understand your question correctly, but the difference between a static inner class to a non-static is that the second needs a reference from the parent class to be created.
It's preferable to create static class, because of "hidden ciclic references" that can be created. For example, it's normal in GUI developing you do something like
public class View {
private Table table;
...
private void addListeners() {
this.table.addListener(new TableSelectionListener());
}
privte class TableSelectionListener implements Table.SelectionListener {
#Overrides
public void selected(SelectionEvent evt) { /* do stuff.*/ }
}
}
Lots of programmers don't realize, but you now have a circular reference between View and Table, because SelectionListener, being non static, saves a reference to its parent. So
View -> Table -> TableSelectionListener --> View
If you declare TableSelectionListener static it will only need the "namespace" from view to be created, but besides that, it will not save a reference to any View unless you save it on a field. But then, you will return to the first problem :P
Hope that helps :)
A non-static nested class is associated and has access to the members of an enclosing class instance:
Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private.
If you implement a Listener of some kind, for example, you usually want to call a method on the outer class when you receive the event. In that case, an inner class is simpler than a nested class with an explicit reference to the outer class instance.
That's often used in GUI components. For example (using an API which doesn't actually exist):
public class CircleView extends View {
private final Circle circle = new Circle();
private final Button button = new Button();
public CircleView() {
circle.setColor(Color.RED);
button.addClickListener(new MyClickListener());
}
private toggleColor() {
circle.setColor(circle.getColor() == Color.RED ? Color.BLUE : Color.RED);
}
private class MyClickListener implements ClickListener() {
#Override
public void onClick() {
// Only possible because of the implicit reference:
toggleColor();
}
}
}
A non-static nested class allows the following in an implicit/magical way:
class MyClass {
public static class MyInnerClass {
final MyClass myClass_this;
public MyInnerClass(MyClass parent) {
// Nested class instance has/keeps access to "parent" object.
// In a nested non-static class the "parent" is -guaranteed- to be
// non-null as the nested class can only be created with
// an instance of the containing class.
myClass_this = parent;
}
public Foo bar() {
// Use myClass_this
// Would be available as MyClass.this or implicit resolution in a
// a nested non-static class.
}
}
}
The rules for scope access are also a bit different but the above should show when it might be useful/desirable. In both cases there is only one type for the inner class (MyClass$MyInnerClass), although there can be many instances.
Wether or not this is a "good" thing to have such non-static nested type behavior is debatable, but it is provided in Java.
However, one case where this "non-static" behavior is extremely useful in Java is with anonymous classes (e.g. event handlers or callbacks) which behave as non-static nested classes; while a "different" construct the same mechanism allows accessing methods defined in the enclosing type. Moving the anonymous classes to non-static nested classes can thus merely be viewed as an extension of this common idiom that also allows exposing the nominative type.
(C# has no notion of a "non-static" nested class, but it is easy to emulate it as per above - although I would argue it's usually better to pass a more-refined interface. In addition, other constructs such as closures minimize the need/use even more.)
I was searching in google for something and I got a code like
public static abstract class LocationResult{
public abstract void gotLocation(Location location);
}
It's a nested class but wondering how it could be accessible ?
It must be a nested class: the static keyword on the class (not methods within it) is only used (and syntactically valid) for nested classes. Such static member classes (to use Java in a Nutshell's common nomenculture) hold no reference to the enclosing class, and thus can only access static fields and methods within it (unlike non-static ones; see any summary of nested classes in Java (also known as inner classes).
It can be accessible like this:
public class EnclosingClass {
public static abstract class LocationResult{
public abstract void gotLocation(Location location);
}
}
EnclosingClass.LocationResult locationResult = ...
Only nested classes can be static. By doing so you can use the nested class without having an instance of the outer class.
So you could create a class extending it using extends Mainclass.LocationResult and use it with Mainclass.LocationResult instance = ...
Why are you not able to declare a class as static in Java?
Only nested classes can be static. By doing so you can use the nested class without having an instance of the outer class.
class OuterClass {
public static class StaticNestedClass {
}
public class InnerClass {
}
public InnerClass getAnInnerClass() {
return new InnerClass();
}
//This method doesn't work
public static InnerClass getAnInnerClassStatically() {
return new InnerClass();
}
}
class OtherClass {
//Use of a static nested class:
private OuterClass.StaticNestedClass staticNestedClass = new OuterClass.StaticNestedClass();
//Doesn't work
private OuterClass.InnerClass innerClass = new OuterClass.InnerClass();
//Use of an inner class:
private OuterClass outerclass= new OuterClass();
private OuterClass.InnerClass innerClass2 = outerclass.getAnInnerClass();
private OuterClass.InnerClass innerClass3 = outerclass.new InnerClass();
}
Sources :
Oracle tutorial on nested classes
On the same topic :
Java: Static vs non static inner class
Java inner class and static nested class
Top level classes are static by default. Inner classes are non-static by default. You can change the default for inner classes by explicitly marking them static. Top level classes, by virtue of being top-level, cannot have non-static semantics because there can be no parent class to refer to. Therefore, there is no way to change the default for top-level classes.
So, I'm coming late to the party, but here's my two cents - philosophically adding to Colin Hebert's answer.
At a high level your question deals with the difference between objects and types. While there are many cars (objects), there is only one Car class (type). Declaring something as static means that you are operating in the "type" space. There is only one. The top-level class keyword already defines a type in the "type" space. As a result "public static class Car" is redundant.
Class with private constructor is static.
Declare your class like this:
public class eOAuth {
private eOAuth(){}
public final static int ECodeOauthInvalidGrant = 0x1;
public final static int ECodeOauthUnknown = 0x10;
public static GetSomeStuff(){}
}
and you can used without initialization:
if (value == eOAuth.ECodeOauthInvalidGrant)
eOAuth.GetSomeStuff();
...
You can create a utility class (which cannot have instances created) by declaring an enum type with no instances. i.e. you are specificly declaring that there are no instances.
public enum MyUtilities {;
public static void myMethod();
}
Sure they can, but only inner nested classes. There, it means that instances of the nested class do not require an enclosing instance of the outer class.
But for top-level classes, the language designers couldn't think of anything useful to do with the keyword, so it's not allowed.
public class Outer {
public static class Inner {}
}
... it can be declared static - as long as it is a member class.
From the JLS:
Member classes may be static, in which case they have no access to the instance variables of the surrounding class; or they may be inner classes (ยง8.1.3).
and here:
The static keyword may modify the declaration of a member type C within the body of a non-inner class T. Its effect is to declare that C is not an inner class. Just as a static method of T has no current instance of T in its body, C also has no current instance of T, nor does it have any lexically enclosing instances.
A static keyword wouldn't make any sense for a top level class, just because a top level class has no enclosing type.
As explained above, a Class cannot be static unless it's a member of another Class.
If you're looking to design a class "of which there cannot be multiple instances", you may want to look into the "Singleton" design pattern.
Beginner Singleton info here.
Caveat:
If you are thinking of using the
singleton pattern, resist with all
your might. It is one of the easiest
DesignPatterns to understand, probably
the most popular, and definitely the
most abused.
(source: JavaRanch as linked above)
In addition to how Java defines static inner classes, there is another definition of static classes as per the C# world [1]. A static class is one that has only static methods (functions) and it is meant to support procedural programming. Such classes aren't really classes in that the user of the class is only interested in the helper functions and not in creating instances of the class. While static classes are supported in C#, no such direct support exists in Java. You can however use enums to mimic C# static classes in Java so that a user can never create instances of a given class (even using reflection) [2]:
public enum StaticClass2 {
// Empty enum trick to avoid instance creation
; // this semi-colon is important
public static boolean isEmpty(final String s) {
return s == null || s.isEmpty();
}
}
Everything we code in java goes into a class. Whenever we run a class JVM instantiates an object. JVM can create a number of objects, by definition Static means you have the same set of copy to all objects.
So, if Java would have allowed the top class to be static whenever you run a program it creates an Object and keeps overriding on to the same Memory Location.
If You are just replacing the object every time you run it whats the point of creating it?
So that is the reason Java got rid of the static for top-Level Class.
There might be more concrete reasons but this made much logical sense to me.
The only classes that can be static are inner classes. The following code works just fine:
public class whatever {
static class innerclass {
}
}
The point of static inner classes is that they don't have a reference to the outer class object.
I think this is possible as easy as drink a glass of coffee!.
Just take a look at this.
We do not use static keyword explicitly while defining class.
public class StaticClass {
static private int me = 3;
public static void printHelloWorld() {
System.out.println("Hello World");
}
public static void main(String[] args) {
StaticClass.printHelloWorld();
System.out.println(StaticClass.me);
}
}
Is not that a definition of static class?
We just use a function binded to just a class.
Be careful that in this case we can use another class in that nested.
Look at this:
class StaticClass1 {
public static int yum = 4;
static void printHowAreYou() {
System.out.println("How are you?");
}
}
public class StaticClass {
static int me = 3;
public static void printHelloWorld() {
System.out.println("Hello World");
StaticClass1.printHowAreYou();
System.out.println(StaticClass1.yum);
}
public static void main(String[] args) {
StaticClass.printHelloWorld();
System.out.println(StaticClass.me);
}
}
One can look at PlatformUI in Eclipse for a class with static methods and private constructor with itself being final.
public final class <class name>
{
//static constants
//static memebers
}
if the benefit of using a static-class was not to instantiate an object and using a method then just declare the class as public and this method as static.