The below question is asked by 4th round interview by project director.
There is a class A . Any number of classes can be derived from A. Constraints is any subclass derived from A or A itself , I should be able to create only one object per class using new keyword. If I try to creating another object it will throw exception.
Class B is derived class of A similarly class C, D, E are also derived classes. The number of class is not limited. Any number of classes can be derived.
The logic of restriction must be inside the class heirarchy not inside the main class.
Sample code of main class.
A obj1 = new A(); // object should create
A obj2 = new A(); // exception should throw
E Obj3 = new E(); //object should create
E obj4 = new E(); //Exception should throw
You can achieve that by storing a static reference to a collection holding instantiated classes (could be any data structure that works), then checking it in the constructor to avoid multiple instantiations:
class A {
private static Set<String> instantiatedClasses = new HashSet<>();
A() {
super();
if (instantiatedClasses.contains(getClass().getName())) {
throw new IllegalStateException(
"Cannot create multiple instances of " +getClass().getName());
}
instantiatedClasses.add(this.getClass().getName());
}
}
class B extends A {
}
And when that's tested:
A a = new A();
System.out.println("Created a: " + a);
try {
a = new A();
} catch (Exception e) {
e.printStackTrace();
}
a = new B();
System.out.println("Created b: " + a);
a = new B();
An output like this is produced:
Created a: stackoverflow.A#506e1b77
java.lang.IllegalStateException: Cannot create multiple instances of stackoverflow.A
at stackoverflow.A.<init>(Main.java:32)
at stackoverflow.Main.main(Main.java:14)
Created b: stackoverflow.B#9807454
Exception in thread "main" java.lang.IllegalStateException: Cannot create multiple instances of stackoverflow.B
at stackoverflow.A.<init>(Main.java:32)
at stackoverflow.B.<init>(Main.java:40)
at stackoverflow.Main.main(Main.java:21)
This is just exploiting the fact that a superclass's constructor is always invoked on instance creation for subclasses. And this will work even for arbitrary inheritance depths.
There are alternative ways of keeping track of classes that have been instantiated, one of which is storing the class, but I believe the necessary part is checking the type in the constructor (where the runtime classes can be seen, and before too late to prevent successful instantiation)
In class A: have a static set of class. Each time the constructor of A is invoked, use this.getClass() to acquire the actual class that wants to be instantiated (keep in mind that any sub class has to call a super constructor first).
If the class is stored in the set, throw that exception. If not, then store the class.
public class A {
private static final Set<Class<? extends A>> INSTANCE_HOLDER = new HashSet<>();
public A() {
if (INSTANCE_HOLDER.contains(this.getClass()))
throw new RuntimeException("can't create more than one instance.");
INSTANCE_HOLDER.add(this.getClass());
}
}
This should be enough to get you started.
For the record: although this should work, it seems like a rather odd idea. If you need singleton objects, rather look into using enums for example. That will prevent all the subtle issues, for example due multiple threads creating objects.
Or, as pointed out by the comment: what about the life time of these objects? You could use a map to ensure that references to your singletons are kept.
But in the end, all of this sounds like violations of the single responsibility principle.
You can use a static instance in A and then in the constructor check if an instance exists and if yes then throw an exception , if it does not then create an object. I am assuming that there is only one object of any class that is either A or a subclass of A. If you mean to say that there should be only instance for each subclass and A , then you may need to create a static HashMap with class Names as the key in A and then check if an instance exists for the particular class by checking for the className from the HashMap.
Related
say, I have the following code (it's a quiz question, so I can run it in my IDE but the logic how it's working is not quite clear to me):
public class Test {
public static void main(String[] args){
A aInstance1 = new A();
A aInstance2 = new B();
A aInstance3 = new C();
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
}
}
class A {
public static void doSth(){
System.out.println("Doing something in A");
}
}
class B extends A {
public static void doSth(){
System.out.println("Doing something in B");
}
}
class C extends B {
public static void doSth(){
System.out.println("Doing something in C");
}
}
The output will be the following:
Doing something in A
Doing something in A
Doing something in A
Thus, my first question is: what is the meaning of the declaration like
A aInstance2 = new B();
i.e., why to create an object of class B declaring it as an instance of class A? How the properties of aInstance2 as an object of class B change compared to the declaration
B aInstance2 = new B();
?
If I remove the word static from the declaration of the methods doSth() in the classes A, B, and C, the output changes to
Doing something in A
Doing something in B
Doing something in C
Thus, when the methods were static, the method doSth() of class A didn't get overridden by those of the subclasses and the output was always "Doing something in A" produced by the objects of different classes, whereas when it became an instance (non-static) method, it gets overridden (if I'm using the right term here). Why is it so?
Removing the word static you are doing Dynamic Binding , because you are pretty much saying : "Even though i know this object is of type A i want it to behave like a B ".
Adding the word static means you are making that method part of the class[Reference type] ,and each time you are calling :"A dosmth()" he knows it only applies to A so it shows the result of the mothod from the class A.
As to what would you do this?I for one learned about this feature from school and studied it even more when i decided to go to interviews becuase it;s one of the things that the interviewer wants to see if you can handle.
If you don't mind I will post a link with information about Static and Dynamic Binding
http://javarevisited.blogspot.ro/2012/03/what-is-static-and-dynamic-binding-in.html
Because static method is based on Reference type .
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
So internally it converts into :
A.doSth();
A.doSth();
A.doSth();
Static methods are class methods while non-static ones are instance methods. Therefore, when you call a static method over an instance you are actually calling it over the declared type of this instance. So, all below calls actually performs the same call: A.doSth() since all instances are declared as type A.
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
When you remove the static keyword, doSth() method becomes an instance method. Instance methods are performed over objects instead of classes. Moreover, when you re-declare an instance method in a subclass, this method is overriden by the subclass. In your example, class B and C override doSth(). Thus, each class provides its own implementation.
Overriding depends on having an instance of a class. A static method is not associated with any instance of a class so the concept is not applicable.
Making static methods works faster, because there's no need to wait until run-time to figure out which method to call.
Overriding in Java simply means that the particular method would be called based on the run time type of the object and not on the compile time type of it.
Illustration -
When doSth() is static:
A aInstance1 = new A();
A aInstance2 = new B();
A aInstance3 = new C();
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
In the above code, the compiler will decide at compile time that without instance it should be called for A. No overriding.
When doSth() is not static:
A aInstance1 = new A();
A aInstance2 = new B();
A aInstance3 = new C();
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
In the above code, the compiler will decide at run time that the method is not static and should be overridden by there respective instances.
static methods are at class level and act on the reference type(LHS of ==) unlike instance level methods which are dynamically dispatched based on the instance type(RHS of ==)
Say I have two classes where SubClass inherits from (extends) SuperClass.
What is the difference between:
SuperClass obj1 = new SubClass();
and:
SubClass obj2 = new SubClass();
Both will look to the constructor of the Superclass and initialise it (the correct one, obviously). Both have access to the superclass implementations. But one is (as far as I am aware) a subclass wrapped in a superclass (the first example) and the other is a subclass object (the second example).
How will this effect the way code is run and interpreted?
What are the real world issues that a developer needs to be aware of regarding how these two objects differ?
Thanks in advance for any help!
The only difference with initializing it as a superclass is that if the subclass implementation has methods which the superclass does not, they will not be accessible via this object reference.
But "internally", this is still an instance of the subclass; so, if you call a method defined in the superclass but the subclass has overriden it, it is the subclass' method which is called: the JVM looks up methods from the more specific to the more general.
As a convoluted example, let us take Object and String:
final Object o = "Hello!"; // in fact this calls new String("Hello!")
o.toString(); // <-- uses String's .toString(), not Object's
// Can't do that: String defines .subString() but Object does not
o.subString(1);
It may help to think what the compiler knows about and what the runtime knows and a simple example:
public class Product {
public double getPrice() {...}
}
public class Book extends Product() {
public int getPageCount() {...}
}
and a simple program:
Product p = new Product();
p.getPrice(); // OK
p.getPageCount(); // compiler error
Book b = new Book();
b.getPrice(); // OK
b.getPageCount(); // OK
Product pb = new Book();
pb.getPrice(); // OK
pb.getPageCount(); // compiler error
// but we can still use the getPageCount() of pb;
((Book)pb).getPageCount(); // compiles
// however if pb was not a Book then you would get a runtime error (ClassCastException)
You can test for the actual class by:
if (pb instanceof Book) {
((Book)pb).getPageCount();
}
This is often necessary when developing classes, but if your code has a lot of instanceof it probably needs rethinking.
SuperClass obj1 = new SubClass();
What you're seeing here is a type of substitutability. What this means is, let's say you make another sub class of SuperClass, SiblingClass. Without using the superclass reference type, we would have to change more code, getters and setters, collections that might want to use it. By referencing them as the supertype, all you need to do is pass in the new SiblingClass object on construction.
Using Javassist, I am creating coupling between classes. However there is obviously a problem when I try to create an instance of a class that takes in parameters. I would really like to be able to grab a CtClass's initializers (if they're not an empty constructor), and then pass in the variables it is expecting. for example, consider I am trying to make an instance of class B in class A:
Public class B{
public int foo;
public char spam;
public B(int bar, char eggs){
foo = bar;
spam = eggs;
}
}
Public class A{
B injected = new B(X,X);
}
currently I use a "isEmpty" check on a class initializer, and if it is not empty, I have attempted the following two approaches. Both give me a no such constructor error:
I think the method "getClassInitializers" should return a CtClass's constructors as an array, but I'm unsure what to do with this array, which eclipse won't even let me declare. I'd like to loop through an array of expected parameters and make dummy variables of that type so I can do something like: B injected B = new B (13, w);
Worse case scenario, I could create a blank class initializer in B so I could do injected B = new B(); I think I should be able to use the makeClassInitializer() method, but that does not work for me, as I still get a no such constructor error.
Solved (kind of):
I was confusing constructors and initializers. It works to use a try/catch block and whenever it enters a catch block, it assumes a non-empty class constructor, in which case it inserts an empty constructor:
try{
//stuff
}catch(Exception e){
//cc is the ctclass object
CtConstructor blank = new CtConstructor(null, cc);
cc.addConstructor(blank);
}
I am still hoping to figure out how to collect the expected parameters instead of injecting empty constructor.
I was asked this question in an interview . I have a base class (say class A) and then two subclasses B and C. Now I have no control over the constructor of B and C(those constructors can't be private , has to be public ) but the requirement is that every instance of B and Cshould be a singleton . How can I achieve this ?
I think I'd do this in the constructor for A. Get it to call this.getClass(), and use that to do a lookup in private HashSet. If you get a hit, then an instance of the class has previously been created, and you throw an exception.
public abstract class A {
private static HashSet<Class<?>> classes = new HashSet<Class<?>>();
public A () {
synchronized (classes) {
Class<?> c = this.getClass();
if (classes.contains(c)) {
throw NotSingletonException("Class " + c + " is not singleton");
}
classes.add(c);
}
}
}
If you arrange that all of A's constructors do this, then subclasses cannot avoid the check. And since the JLS won't let you put a try / catch around a this() or super() call, the constructor for the subclass can't ever return normally once that exception has been thrown.
I'd say that this is a pretty hard interview question ...
#emory comments:
What if B and C are not final? Then I could create classes B1, B2, C1, C2, etc.
The problem here (if it counts as a problem) is that the B1 and B2 instances are also B instances, and that means that the B instance is no longer a singleton ... depending on the definition of singleton you are aspiring to implement.
I can see a couple of ways of dealing with this:
You could reflectively test the subclass modifiers see if the classes are final, and refuse to create instances of non-final classes ... just in case.
You could replace the HashSet<Class> with a List<Class>. Then each time the A constructor is called, it would iterate over the list calling elem.isAssignableFrom(c) for each element class. If any call returns true, the (strict) singleton invariant is violated so an exception should be thrown.
The logic may need to be adjusted depending on the model of singleton-ness you are trying to enforce, but the general solution applies: record the classes and examine / compare new classes with previous ones.
I am showing it for the class B
Though you can use Double checked locking, and synchronized on method to do it.. i am showing you a quick and dirty way of doing it...
public class B {
private static B b = new B();
private B() {}
public static B getInstance() {
return b;
}
}
Say if I have a class named Car I can use the following line of code in certain situations.
Car.class
My question is there a way I can make the same type of call if a user supplies a class name at run time. Have tried something similar to the below but no joy, is there a way i can do it.
String className = "Car";
Class.forName(className ).class;
Also I need to be able to cast dynamically, if the user specifies a list of objects I need to be able to dynamically cast.
e.g. instead of Car myCar = (Car) object
I need to be able to have to the user specify the name/type of class at run time so that I need to be able to do something along the lines of ClassName myObj = (ClassName) object.
Class.forName("Car") already returns the same as Car.class.
For casting, you can then use Class.forName("Car").cast(object), which would return a Car object. Take a look at the API, mostly the java.lang.Class part of it.
Also, since you're casting # runtime, there's no type safety, and you should check whether object extends or implements Car before doing it, otherwise you'll get an exception. A question I asked ~ a year ago and the answers there may be relevant to you as well.
Though, as others already said, this smells & you could probably redesign it in a better way, also note that this type of casting will typically be pretty slow because Java needs to examine the type hierarchy (it needs to throw a ClassCastException if it can't cast to Car).
Given the nature of the question, most of the answers to this are straight from the Reflection API documentation. I would suggest you take a look at this: http://docs.oracle.com/javase/tutorial/reflect/class/index.html. If this does not help and you need help with something specific, we can look at that.
What you are looking for is a feature called Reflection in the Java programming language.
It allows an executing Java program to examine or "introspect" upon itself, and manipulate internal properties of the program. For example, it's possible for a Java class to obtain the names of all its members and display them.
A Simple Example from http://java.sun.com
import java.lang.reflect.*;
public class DumpMethods {
public static void main(String args[])
{
try {
Class c = Class.forName(args[0]);
Method m[] = c.getDeclaredMethods();
for (int i = 0; i < m.length; i++)
System.out.println(m[i].toString());
}
catch (Throwable e) {
System.err.println(e);
}
}
}
For an invocation of:
java DumpMethods java.util.Stack
the output is:
public java.lang.Object java.util.Stack.push(
java.lang.Object)
public synchronized
java.lang.Object java.util.Stack.pop()
public synchronized
java.lang.Object java.util.Stack.peek()
public boolean java.util.Stack.empty()
public synchronized
int java.util.Stack.search(java.lang.Object)
Here is an example of creating objects at runtime:
import java.lang.reflect.*;
public class constructor2 {
public constructor2()
{
}
public constructor2(int a, int b)
{
System.out.println(
"a = " + a + " b = " + b);
}
public static void main(String args[])
{
try {
Class cls = Class.forName("constructor2");
Class partypes[] = new Class[2];
partypes[0] = Integer.TYPE;
partypes[1] = Integer.TYPE;
Constructor ct
= cls.getConstructor(partypes);
Object arglist[] = new Object[2];
arglist[0] = new Integer(37);
arglist[1] = new Integer(47);
Object retobj = ct.newInstance(arglist);
}
catch (Throwable e) {
System.err.println(e);
}
}
}
You can read more about it here and here - for indepth view
Also look here:
What is reflection and why is it useful?
You want to interact with myObj, so rather than going through these gymnastics, think about adding an interface that models the interactions you want to have with the objects, then use that interface in the code. The classes supplied by the user can then be validated to implement the necessary interface and errors raised appropriately.
The expression Car.class returns the java.lang.Class object for class Car.
A statement Class.forName("Car") will also return the java.lang.Class object for class Car (assuming that class Car is in the default package). Note: No need to append .class; that would give you the Class object of class Class itself, which is not what you want.
Class Class has methods to check if an object is an instance of the class that the Class instance represents (hope this is not too confusing...). Since you don't know the name of class Car at compile time, you're not going to have any kind of compile time type safety.
Lookup the API documentation of java.lang.Class.