Is it possible to have a nested singleton in java? - java

I was surprised to see that a private constructor of a nested class is still callable from the nesting class. For example:
public class A{
public void foo(){
//private constructor of B
//can be called from A
B b = new B();
}
//nested class
public static class B{
private B(){
}
}
}
Does this mean that there is no way to enforce the singleton pattern on a nested class? Or am I missing something fundamental here?

It's not just the constructor, any private field or method is accessible:
public class Main {
public static void main(final String[] args) {
final B b = new B();
b.whut();
}
public static class B {
private B() {
System.out.println("hey");
}
private void whut() {
System.out.println("wut?");
}
}
}
Outer classes have access to private fields of their nested classes:
http://docs.oracle.com/javase/tutorial/java/javaOO/nested.html

Does this mean that there is no way to enforce the singleton pattern on a nested class?
It depends what you mean by "enforce".
If you mean, can you get the compiler to prevent foo from breaking your 'singleton' invariant - then "No". (Or at least, not unless you make 'B' a non-nested class first ...)
However, the outer class and the nested classes are all defined in the same source file, and should be considered as part of the same unit of abstraction. (And in fact, the fact that A.foo() can call A.B.B means the latter is true in a very real sense.) Therefore, it is the responsibility off A and everything within it to maintain the entire abstraction's invariants ... including singleton-ness of B.
From that perspective, a foo method that breaks the invariant is no different to a hypothetical method on a non-nested "singleton" class that breaks the invariant; e.g.
public Single {
private static Single s = new Single();
public static Single getInstance() { return s; }
private Single() { ... }
public void foo() {
Single ss = new Single(); // breaks the invariant!!
...
}
}
Note the problem ... in both cases ... is that the abstraction is breaking its own invariants.

Does this mean that there is no way to enforce the singleton pattern on a nested class?
It is anyway difficult to implement the singleton (anti) pattern in Java. enums offer a good way, and they work with nesting too:
Does this mean that there is no way to enforce the singleton pattern on a nested class?
enum Outer {
O;
enum Inner { I }
}

Related

Extending an inner class in java

I'm having trouble trying to implement this statement I read in Oracle's Docs about Inheritance when it comes to inner classes.
The statement :
A nested class has access to all the private members of its enclosing class—both fields and methods. Therefore, a public or protected nested class inherited by a subclass has indirect access to all of the private members of the superclass.
In order to test this out i.e. to see if I can achieve the above I created a top level class OC1 which had an inner class IC1 ,then I created another top level class OC2 which extended IC1.
Before I could even start writing a single method , the IDE stopped me at the OC2 class body itself saying
"No enclosing instance of type DataStructure is available due to some intermediate constructor invocation"
I read some other answers and most of them point to either
a) Changing the inner class to static Nested Class -- it resolves the error
b) The whole scenario is unnecessary and convoluted.
Here is the code:
public class DataStructure {
// Create an array
private final static int SIZE = 15;
private int[] arrayOfInts = new int[SIZE];
public DataStructure() {
// fill the array with ascending integer values
super();
for (int i = 0; i < SIZE; i++) {
arrayOfInts[i] = i;
}
}
//other methods
//IC1
protected class instanceArr{
private int a = 8;
private static final int B = 4;
protected instanceArr(){
}
protected void doSomething(){
System.out.println("arrayOfInts[] is accessible " + arrayOfInts[6]);
}
}
//main method
}
OC2
public class DataStructureChild extends DataStructure.instanceArr{
public DataStructureChild(){
}
}
I know that the scenario is not an ideal one but I don't want to change inner class to static nested class - it would defeat my purpose of basically trying to see whether arrayOfInts is accessible without OC1's instance in hand.
Am I misinterpreting this statement ? if not then kindly point me in the correct direction.
PS - this is my first question here - apologies in advance if some guidelines were flouted.
Yes, this is a Trap caused by Java's synthetic sugar. You think the inner-non-static-class have the default-no-arguments-constructor but that is wrong. Internally the constructor of IC1 have the OC1 as first argument in the constructor - even if you can not see it.
Thats why the OC2 constructor must use the OC1 as constructor-argument:
public DataStructureChild(DataStructure argument) {
}
Unfortunaltely this is not enougth, you need to get sure the argument is not-null:
public DataStructureChild(DataStructure argument) {
argument.super();
}
It looks very wierd but it works.
You can do this since you inherit access to the inner class of the parent.
class DataStructureChild extends DataStructure {
public DataStructureChild() {
}
public void foo() {
InstanceArr ins = new InstanceArr();
ins.doSomething();
System.out.println(ins.a);
}
}
But could you please give a link or explain where you read the following? A nested class has access to all the private members of its enclosing class—both fields and methods. Therefore, a public or protected nested class inherited by a subclass has indirect access to all of the private members of the superclass.
The first part I knew about. But I never considered a separate class extending another classes inner class. Especially since there is usually an implicit relationship between classes and their enclosed inner classes.
Edit:
I believe you misunderstood the statement.
It says that your subclass inherits the inner class. That is true.
It also says that once done you have access to the private values of the inherited inner class. That is also true as demonstrated above:
So it was just talking about access the inner class via inheritance, not extending it directly.
However, if you really want to do have that kind of inheritance relationship without passing references around, you can go this route.
public class Inheritance extends Outer.Inner {
public Inheritance() {
new Outer().super();
}
public static void main(String[] args) {
new Inheritance().start();
}
public void start() {
System.out.println(a);
method();
}
}
class Outer {
public Outer() {
}
protected class Inner {
protected int a = 10;
protected Inner() {
}
protected void method() {
System.out.println("This is a private message");
}
}
}

How can I make fields in nested class real private?

I have a nested (static) class with a private field and a setter method for this field.
public class Outer{
private static class Inner{ // List node
private String fieldA;
// ...other members...
public void setA(String fieldA)
{
//.. do importent stuff before setting fieldA
this.fieldA = fieldA;
}
}
}
Now we had a bug because the fieldA is accessed directly (and not by setter method setA) by Outer class although the field fieldA is private. How can I enforce developers to use the setter method instead of directly accessing the field?
I have read the related topic Access modifiers inside a private static nested class in Java that states that it is by design. But is there a workaround to ensure using setter method by outer class?
If the class must not be moved to outside of Outer, you should define an interface for Inner and use only that. If you have only few instances and this is not a performance critical point of your application, you could just create anonymous implementations of that interface. The class isn't static anymore but at least it's a short and readable solution.
private static interface Inner {
void setA(String a);
}
private static Inner createInner() {
return new Inner() {
private String a;
#Override
public void setA(String a) {
this.a = a;
}
};
}
If you want to keep the class static, I don't see many options to hide anything from the outer class. You can try to make it more obvious that the inner class should be used carefully.
It looks a bit strange, but you could move the implementation into the interface like in the following example - that doesn't really prevent anyone from using Inner.InnerImpl, but it should imply that the class InnerImpl belongs to Inner and is not be used directly.
public class Outer{
private static interface Inner {
static class InnerImpl implements Inner {
private String a;
#Override
public void setA(String a) {
this.a = a;
}
}
void setA(String a);
}
// either instantiate directly or again wrap it in a `createInner()` method
// Inner inner = new Inner.InnerImpl();
}
Actually here is another quite simple option. I think for this special case you could justify introducing a new naming convention to avoid accidental use of properties.
private static class Inner {
private String _a;
public void setA(String a) {
this._a = a;
}
}

Why wouldn't you make a nested class static?

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.)

Return a private class implementing an interface keeping the implementation private

Static method M returns an object implementing interface A:
interface A { ... }
static A M() { ... }
Within M I would like to construct an object of type B and return that, given that B implements A:
class B implements A { ... }
I do not want client code to know anything about how B is implemented, I would prefer for B not to be a static class, B must be immutable and there could be different B handed to different clients. I want to prevent instantiation of B outside method M at all costs (short of reflection, as one user commented).
How can I achieve the above? Where and how should I implement B? Could you please provide a short code example?
My main problem is: how can I have "different Bs?"
A static inner class is probably your best bet. You won't be able to "prevent instantiation of B at all costs" since with reflection, client code can bypass all access modifiers.
You can use anonymous inner class that won't be called B (is anonymous) but will implement A for example
interface A {
void someMethod();
}
public class Test {
static A M() {
return new A() {// it will create and return object of anonymous
// class that implements A
#Override
public void someMethod() {
}
};
}
}
Without using reflection object of anonymous class can be created only by method M. Also it can't be extended so it is good first step to immutability.
You could also use a Proxy implementation to hide the implementation class further
public interface A {
public Object getValue();
}
public class Factory {
public static A newInstance() {
return new ProxyA(AImpl);
}
}
public class ProxyA implements A {
private A proxy;
public ProxyA(A proxy) {
this.proxy = proxy;
}
public Object getValue() {
return proxy.getValue();
}
}
All this is really doing is hiding the implementation of A under another layout and makes it difficult to create a instance of ProxyA
But as #Asaph points out, with reflection, it becomes next to near impossible to truly guard against people accessing various parts of the classes and objects...
You could also separate your interface and implementations via different Classloaders, so that you only ever expose the interface's to the developers and implementations are delivered by dynamic class loading them at runtime. While not solving the underlying problem, it further complicates the matters for those trying to circumvent your factory.
IMHO

Why are you not able to declare a class as static in Java?

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.

Categories

Resources