I was having a query that is if we have constructor in the class as below..
class A
{
A{}
}
Now what is the alternative to the constructors , I have gone for the approach that is static factory methods
class A
{
public staic A getinstance()
{
return new A();
}
}
In the above approch as per the analysis it will return immutable object but I have doubt on this analysis as the object that can be return with static factory method and can later be changed on , How to make it completely immutable..!! please advise..!!
Immutability is not related to the manner you create your objects. i.e. from constructors or factory methods.
JDK provides some ways to do this for Collections, using Collections.unmodifiableCollection and related methods.
You can also incorporate it into your design, which becomes useful when working with concurrent applications.
A complete strategy for this is given here : http://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html
alternative to the constructors : static factory methods are not alternative to constructors. But you can have block intialization which is equivalent to the constructors, but disadvantage is you can not pass arguments to it like :
class B {
private int i;
//intialization block, can not pass arguments like constructor
{
i=2;
}
//getter and setters
}
.
class A
{
public staic A getinstance()
{
return new A();
}
}
--> well this class will not return immutable object. To make class immutable, make class final, all members private and final, provide only getter methods and parameterised constructor. See below example :
final class A
{
final private int b;
public A(int b)
{
this.b = b;
}
public int getB() {
return this.b;
}
}
Related
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;
}
}
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 }
}
I have a superclass that I would like to forward a static method called getInstance() to all subclasses.
When creating an instance of a subclass, I then register the instance in the superclass (perhaps using a hashtable, where the key is based on getClass()). Then, I wish to use the aforementioned static method ( getInstance ) where the superclass method will return the instance of the correct type.
For example, I have a superclass A, and a subclass B extends A.
I want to write a static method A.getInstance(); when called from B (B.getInstance()), I would like it to return the instance of B that I stored earlier.
Its kinda hard to explain, but I am going to be using this superclass a lot, and I would rather not code a getInstance method into every single subclass.
How would I go about doing something like this?
edit: I just realized that my question may be misconstrued as creating a NEW instance of the object. I have already created the instance, and i wish to get the existing instance of the class
As many others have noted in the comments, what you are trying to do is not possible with static methods. Also, you should try to avoid static methods whenever possible because they can result in a testing and maintanance nightmare (*).
You named your method "getInstance", so I guess what you want to do is a mix of Factory- and Singleton patterns. Here is some information to get you started about these patterns:
Singleton: http://en.wikipedia.org/wiki/Singleton_pattern
Factory Method: http://en.wikipedia.org/wiki/Factory_method_pattern
Abstract Factory: http://en.wikipedia.org/wiki/Abstract_factory
Both should not be coded by hand in these days (*) - Have a look at a good "Dependency Injection" (DI) container like Google Guice or Spring. I am not 100% sure what exactly you want to achieve, but it looks like a DI container will do it for you.
Edit: This is a response to an edit of the question. You want to receive a cached instance of the sub classes. In this case, I would still advise against static methods. You could create a singleton instance of a "BCache" class (using a DI container or programming it by hand), and then use this cache object to look up your registered objects. Using Guice as a DI container, it could look like this (warning, untested):
#Singleton
public class BCache {
private Map<Class<? extends B>, B> cache = ...;
public <T> T getInstance(Class<? extends T> type) {
return (T) cache.get(type);
}
}
I still think it would be possible to get rid of the cache class completely using a DI container, though. Again, this is untested code, using Guice, but it could look like this:
#Singleton
public class A extends B {
public A() {
//I am not sure if you need to register in this case, because your
//DI container keeps track of the singleton instances.
super.register(this);
}
}
public class SomeClassUsingA {
#Inject private A a;
}
(*) Note that "all generalizations are wrong", that is, in some projects it might make sense, but in most it will not.
You can't do exactly what you want with the static methods, in good OOP way. You can can do something with the reflection or bunch of if .. else if.
You however, should use some well defined design patterns like Abstract fectory or Factory method. This is the way you should go, like someone said "Don't invent warm water".
You can always assign a subClass instance to a superClass reference. Therefore your superClass's static methods can set or get a subClass instance. But make sure to cast the returned instance before using.
public class A {
private static A a;
/**
* #param a the a to set
*/
public static void setA(A a) {
A.a = a;
}
/**
* #return the a
*/
public static A getA() {
return a;
}
public class B extends A {
private int index = 0;
/**
* #param index the index to set
*/
public void setIndex(int index) {
this.index = index;
}
/**
* #return the index
*/
public int getIndex() {
return index;
}
Usage:
public static void main(String[] args) throws Exception {
B b = new B();
A.setA(b);
B c = (B) A.getA();
System.out.println(c.getIndex());
}
Change form getInstance() to getInstance(String class)
in the superclass:
public static A getInstance(String class){
if(class.equals("A")){
RegisterObject(...);//User defined method
return new A(...);
}
else if(class.equals("B")){
RegisterObject(...);//User defined method
return new B(...);
}
else if(class.equals("C")){
RegisterObject(...);//User defined method
return new C(...);
}
//... and so on
}
Static methods are cannot know which class is used to invoke them. If for example you have class A and B that extends A and static getInstance() implemented in A there is no difference whether you invoke getInstance() using A or B. Moreover attempt to call B.getIntance() will produce compilation warning (at least in Eclipse).
However you can pass the class as a parameter of getInstance():
public class A {
public static <T extends A> T getInstance(Class<T> clazz) {
return clazz.newInstance(); // I do not catch exceptions here: do it yourself
}
}
public class B extends A {
}
...............
B b = A.getInstance(B.class);
You can do like this way,
class A{
public static A getInstance(){
return new A();
}
#Override
public String toString() {
return "inside A";
}
}
class B extends A{
public static A getInstance(){
return new B();
}
#Override
public String toString() {
return "inside B";
}
}
inside main :
public static void main(String[] args) {
A a1 = A.getInstance();
A a2 = B.getInstance();
System.out.println(a1.toString());
System.out.println(a2.toString());
}
A friend of mine was asked that question in his on-phone job interview a couple of days a go.
I don't have a clue. can anyone suggest a solution?
(His job interview is over. just out of curiosity now )
10x.
Mark constructor as private
Provide a static method on the class to create instance of a class. This will allow you to instantiate objects of that class
I don't know what they mean exactly mean by a final class. If they mean a class that cannot be extended by inheritence, than clearly this cannot be done, except by marking that class with final (or sealed, or whatever the language keyword is).
But if the mean final as in immutable, such that a derived class can't modify the value of the fields in the class,than the base class should have all of the fileds and accessor methods private.
Create a private constructor without parameters?
public class Base
{
private Base()
{
}
}
public class Derived : Base
{
//Cannot access private constructor here error
}
Make all the constructors of that class as private to stop inheriting, Though not recommended.
public class Immutable {
private int val;
public Immutable(int v)
{
this.val = v;
}
public int getVal() { return this.val; }
}
You can make your class immutable without using final keyword as:
Make instance variable as private.
Make constructor private.
Create a factory method which will return the instance of this class.
I am providing immutable class here in Java.
class Immutable {
private int i;
private Immutable(int i){
this.i = i;
}
public static Immutable createInstance(int i){
return new Immutable(i);
}
public int getI(){return i;}
}
class Main {
public static void main(string args[]){
Immutable obj = Immutable.createInstance(5);
}
}
Static classes can't be inherited from
Lets say I have a concrete class Class1 and I am creating an anonymous class out of it.
Object a = new Class1(){
void someNewMethod(){
}
};
Now is there any way I could overload the constructor of this anonymous class. Like shown below
Object a = new Class1(){
void someNewMethod(){
}
public XXXXXXXX(int a){
super();
System.out.println(a);
}
};
With something at xxxxxxxx to name the constructor?
From the Java Language Specification, section 15.9.5.1:
An anonymous class cannot have an
explicitly declared constructor.
Sorry :(
EDIT: As an alternative, you can create some final local variables, and/or include an instance initializer in the anonymous class. For example:
public class Test {
public static void main(String[] args) throws Exception {
final int fakeConstructorArg = 10;
Object a = new Object() {
{
System.out.println("arg = " + fakeConstructorArg);
}
};
}
}
It's grotty, but it might just help you. Alternatively, use a proper nested class :)
That is not possible, but you can add an anonymous initializer like this:
final int anInt = ...;
Object a = new Class1()
{
{
System.out.println(anInt);
}
void someNewMethod() {
}
};
Don't forget final on declarations of local variables or parameters used by the anonymous class, as i did it for anInt.
Here's another way around the problem:
public class Test{
public static final void main(String...args){
new Thread(){
private String message = null;
Thread initialise(String message){
this.message = message;
return this;
}
public void run(){
System.out.println(message);
}
}.initialise(args[0]).start();
}
}
I know the thread is too old to post an answer. But still i think it is worth it.
Though you can't have an explicit constructor, if your intention is to call a, possibly protected, constructor of the super class, then the following is all you have to do.
StoredProcedure sp = new StoredProcedure(datasource, spName) {
{// init code if there are any}
};
This is an example of creating a StoredProcedure object in Spring by passing a DataSource and a String object.
So the Bottom line is, if you want to create an anonymous class and want to call the super class constructor then create the anonymous class with a signature matching the super class constructor.
Yes , It is right that you can not define construct in an Anonymous class but it doesn't mean that anonymous class don't have constructor. Confuse...
Actually you can not define construct in an Anonymous class but compiler generates an constructor for it with the same signature as its parent constructor called. If the parent has more than one constructor, the anonymous will have one and only one constructor
You can have a constructor in the abstract class that accepts the init parameters. The Java spec only specifies that the anonymous class, which is the offspring of the (optionally) abstract class or implementation of an interface, can not have a constructor by her own right.
The following is absolutely legal and possible:
static abstract class Q{
int z;
Q(int z){ this.z=z;}
void h(){
Q me = new Q(1) {
};
}
}
If you have the possibility to write the abstract class yourself, put such a constructor there and use fluent API where there is no better solution. You can this way override the constructor of your original class creating an named sibling class with a constructor with parameters and use that to instantiate your anonymous class.
If you dont need to pass arguments, then initializer code is enough, but if you need to pass arguments from a contrcutor there is a way to solve most of the cases:
Boolean var= new anonymousClass(){
private String myVar; //String for example
#Overriden public Boolean method(int i){
//use myVar and i
}
public String setVar(String var){myVar=var; return this;} //Returns self instane
}.setVar("Hello").method(3);
Peter Norvig's The Java IAQ: Infrequently Answered Questions
http://norvig.com/java-iaq.html#constructors - Anonymous class contructors
http://norvig.com/java-iaq.html#init - Construtors and initialization
Summing, you can construct something like this..
public class ResultsBuilder {
Set<Result> errors;
Set<Result> warnings;
...
public Results<E> build() {
return new Results<E>() {
private Result[] errorsView;
private Result[] warningsView;
{
errorsView = ResultsBuilder.this.getErrors();
warningsView = ResultsBuilder.this.getWarnings();
}
public Result[] getErrors() {
return errorsView;
}
public Result[] getWarnings() {
return warningsView;
}
};
}
public Result[] getErrors() {
return !isEmpty(this.errors) ? errors.toArray(new Result[0]) : null;
}
public Result[] getWarnings() {
return !isEmpty(this.warnings) ? warnings.toArray(new Result[0]) : null;
}
}
It doesn't make any sense to have a named overloaded constructor in an anonymous class, as there would be no way to call it, anyway.
Depending on what you are actually trying to do, just accessing a final local variable declared outside the class, or using an instance initializer as shown by Arne, might be the best solution.
In my case, a local class (with custom constructor) worked as an anonymous class:
Object a = getClass1(x);
public Class1 getClass1(int x) {
class Class2 implements Class1 {
void someNewMethod(){
}
public Class2(int a){
super();
System.out.println(a);
}
}
Class1 c = new Class2(x);
return c;
}