Design a class such that only one instance of the class and any of its sub-classes can be created. To clarify: Assume A is such a class and B is derived from A. B does not have any special code apart from extending A.
class A {
// code of class A
}
public class B extends A{
public static void main(String[] args)
{
new A(); // works fine.
new A(); // causes an exception
new B(); // works fine as this is the first instance of B
new B(); // causes an exception.
}
}
But we need to create the object with the new keyword.
I try in static value define in parent but this does not help.
class A {
private static Map<Class<? extends A>, A> instances = new HashMap<>();
public A() {
synchronized (A.class) {
if (instances.containsKey(this.getClass())) {
throw new IllegalStateException();
}
instances.put(getClass(), this);
}
}
// code of class A
}
public class B extends A {
public static void main(String[] args) {
new A(); // works fine.
new A(); // causes an exception
new B(); // works fine as this is the first instance of B
new B(); // causes an exception.
}
}
When you create an instance of A or any subclass of A, the constructor of A it is called.
The constructor checks if an instance of A is present in the Map instances.
If an instance of the current class exists, an exception is thrown.
If no instance of the current class exists (when no exception is thrown), the current object is saved to instances.
The Map is static so the same Map is used across all instances (It obviously would not work if every instance of A had its own Map).
The synchronized block makes sure that the map access is thread safe by locking the Class object of A. Locking the current Class object is not thread safe as the put method of HashMap is not thread safe when creating new objects.
You can also lock instances or use a Set of Classes as described in this answer from oleg.cherednik.
class A {
private static final Set<Class<? extends A>> INSTANCES = new HashSet<>();
public A() {
synchronized (INSTANCES) {
if (INSTANCES.contains(getClass()))
throw new RuntimeException("duplication: " + getClass().getSimpleName());
INSTANCES.add(getClass());
}
}
// code of class A
}
class B extends A {
public static void main(String[] args) {
new A(); // works fine.
new A(); // causes an exception
new B(); // works fine as this is the first instance of B
new B(); // causes an exception.
}
}
Related
I was revising some of the old school concepts of Java in order to solve one problem . I have written the following code where i am trying the create objects of multiple class in that same classes and calling the methods with those objects from the main.
class a {
public void display() {
System.out.println("inside class a");
a a1= new a();
}
}
class b {
public void display() {
System.out.println("inside class b");
b b1= new b();
}
}
public class one {
void display() {
System.out.println("inside class one");
}
public static void main(String[] args) {
one o = new one();
a1.display();
b1.display();
o.display();
}
}
I am getting object cannot be resolved error. My question is what i need to change to let the above code work. And, do i need to always declare objects inside the main().
Any help will be highly appreciated
I'm not really sure why you would want to do that, but assuming you're just wondering about the possibility to implement such a thing - yes, it can be done.
You can create an instance of a class inside that same class, like so:
public class A {
public static A instance = new A();
public void display() {
System.out.println("inside class A");
}
}
Pay attention to the static modifier in the above code; it allows you now to access instance from another place (class, method, main) like so:
A.instance.display();
If you want to know whether you can declare a variable inside a method, and not a class, and make it accessible from another method, then the answer is - no, you cannot.
Yes you need to declare objects inside the main()
class a {
public void display() {
System.out.println("inside class a");
}
}
class b {
public void display() {
System.out.println("inside class b");
}
}
public class one {
void display() {
System.out.println("inside class one");
}
public static void main(String[] args) {
a a1= new a();
b b1= new b();
one o = new one();
a1.display();
b1.display();
o.display();
}
}
Don't know what you want to achieve and yes you should create object of class a and class b inside main functions to use instance methods of these classes.
package com.stack.overflow;
class a
{
public void display()
{
System.out.println("inside class a");
//a a1= new a(); ---> No need of this line as you can
// directly access instance variables and methods directly without
// creating any object or you can also use **this** keyword for the same
}
}
class b
{
public void display()
{
System.out.println("inside class b");
//b b1= new b(); ---> No need of this line as you can
// directly access instance variables and methods directly without
// creating any object or you can also use **this** keyword for the same
}
}
public class one
{
void display()
{
System.out.println("inside class one");
}
public static void main(String[] args) {
one o = new one();
a a1=new a();
b b1=new b();
a1.display();
b1.display();
o.display();
}
}
You may find the answer to your confusion easily - #ratul-sharker : a1 & b1 must be declared and instantiated inside the main. as well as other answers here correcting your code.
The real question is your notion of scoping and lifetime of variables - Not only a1 and b1 lie inside the classes a and b but they have been instantiated inside methods so they are local. So, try to understand the difference between field variables and local variables - their lifetimes and scopes are vastly different.
Accessing a local variable directly like that(which will be instantiated when the method is called) is like asking asking for a result from future in the present. Note that field variables will remain as long as object is alive but the local variables will remain only for the duration of the method call.
Hope it is clear to you now.
Also, your question:
My question was is it possible to create an object of an class in the
same class and call it from main?
Yes. Because main is a static method so it is not bound to an object like non-static method does. static methods are class level while non-static methods are object level. You can also create an instance in a non-static method for that matter.
I have written a piece of code as below.
that gives error instead of printing SUCCESS.
class A
{
{
new B();
}
static class B
{
{
new A().new C();
}
}
class C
{
{
System.out.println("SUCCESS");
}
}
}
public class Main
{
public static void main(String[] args)
{
new A();
}
}
Please help me where it fails.
You got an infinite chain of constructor calls that starts with new A();, which
creates an instance of A, which creates an instance of B (due to new B(); in the instance initializer block of class A), which creates another instance of A (due to new A().new C(); in the instance initializer block of class B), which creates another instance of B, and so on...
This leads to StackOverflowError.
The instance of C is never created, which is why System.out.println("SUCCESS"); is never executed.
Can someone please elaborate me in detail the following scenario, it would be more convenient if the explanation includes the memory allocation and its reference for the three cases :
How is the flow executed in the three cases ?
Why the flow differ in the three cases ?
Though there is a circular dependency between the two classes why the case 1 alone gets executed where as the remaining cases were failed ?
CASE ONE
namespace CircularDependency_1
{
class Program
{
static void Main(string[] args)
{
A a = new A();
Console.WriteLine("executed");
Console.ReadLine();
}
}
public class B
{
public static A a = new A();
public B()
{
Console.WriteLine("Creating B");
}
}
public class A
{
public static B b = new B();
public A()
{
Console.WriteLine("Creating A");
}
}
}
OUTPUT
Creating A
Creating B
Creating A
executed
CASE TWO
namespace CircularDependency_1
{
class Program
{
static void Main(string[] args)
{
A a = new A();
Console.WriteLine("executed");
Console.ReadLine();
}
}
public class B
{
public static A a;
public B()
{
a = new A();
Console.WriteLine("Creating B");
}
}
public class A
{
public static B b;
public A()
{
b = new B();
Console.WriteLine("Creating A");
}
}
}
OUTPUT
Process is terminated due to StackOverflowException.
CASE THREE
namespace CircularDependency_1
{
class Program
{
static void Main(string[] args)
{
A a = new A();
Console.WriteLine("executed");
Console.ReadLine();
}
}
public class B
{
public A a;
public B()
{
a = new A();
Console.WriteLine("Creating B");
}
}
public class A
{
public B b;
public A()
{
b = new B();
Console.WriteLine("Creating A");
}
}
}
OUTPUT
Process is terminated due to StackOverflowException.
#Versatile, you are close, but not right. The reason why the first case executes and two other cases fail, is not just because the objects are created inside the constructor or inside the class (outside of the constructor). To prove this, try making the a and b fields not static in the B and A classes (Case one), respectively; and you will see that it will fail, even though the objects are created outside of the constructor.
Case 2 and 3 fail because of the reasons explained by #Versatile.
Case 1 executes because of static members.
Let's examine the flow:
In the Main method the line A a = new A() begins creating the a object. In this process, an object of class B will be created because of the line public static B b = new B() - this very line will start creating another object of the class A because of the line public static A a = new A() in the body of class B. Now, here comes the magic (that doesn't fire a circular dependency). This line, public static A a = new A() will start creating another object of class A, while creating this object it won't create another object of class B because it is a static member of A, and it was already created. As we know, static members of a class are shared among all instances of the class. Therefore, it won't trigger the creation of another object of class B. In total, we end up with three instances of the classes in the order : A, B, A.
UPDATE
It is interesting to observe, in the first case, what happens if we initialize the static member inside the constructor. Even though, the A and B classes declare static members, the execution will fail due to circular dependency. This is because the static members are not initialized before the constructor is executed.
1.How is the flow executed in the three cases ?
First the static void Main() gets called and then the constructor of object A is called because of code line A a = new A();
2.Why the flow differ in the three cases ?
3.Though there is a circular dependency between the two classes why the case 1 alone gets executed where as the remaining cases were failed ?
Both the above scenarios are observed for the same reason. If you look closely, you assign memory as follows.
Case1 in the class and not the constructor. i.e.
public class A
{
public static B b = new B();
}
Moreover the object is static so it will be created only once and as this is created once the memory which is assigned in the same line gets executed only once.
Case 2 and Case 3: Memory to Objects A and B is assigned in the constructor i.e. in constructor of A the memory is assigned to B and in constructor of B memory is assigned to A, which results in calling the respective class constructors again and again until it throws an exception.
Class A {
dog()
}
Class B extends A {
cat()
}
public static void main(String args[]) {
A obj1 = new A();
B obj2 = new B();
A obj3 = new B();
}
when class A object is created then obj1 will call dog(),whenClass B's object is created then obj2 will call cat() and dog().but A obj3= new B() is created which method should be called?please answer
Thanks
To give a quick and dirty answer, from what I think you mean:
Both methods CAN be called. (In your example, neither method WILL be called because, excluding the other errors, you aren't actually calling any of the methods)
I won't get fully into polymorphism but I will try my best:
If you have:
Class A {
public void doSomething() {
System.out.println("Bark!");
}
}
and
Class B extends A{
public void doSomething() {
System.out.println("Meow!");
}
}
and I do
public static void main(String[] args) {
A obj1 = new A();
B obj2 = new B();
A obj3 = new B();
// And you want to see what happens when you do:
obj1.doSomething();
// Prints Bark!
obj2.doSomething();
// Prints Meow!
obj3.doSomething();
// Prints Meow!
}
Notice that the important thing here is that BOTH classes have the exact same name for the method, even
though it does different things!
That is the (I think) key concept to polymorphism you are trying to understand: You
can redefine what a method does in a subclass! HOWEVER, to redefine a method, the method has to have the same
name! Then, the compiler will pick the version of the method that is defined at the lowest level.
In your example
Class A {
public void dog() {
System.out.print("Dog!");
}
}
Class B extends A {
public void cat() {
System.out.println("Cat!");
}
}
public static void main(String args[]) {
A obj1 = new A();
B obj2 = new B();
A obj3 = new B();
obj1.dog()
// This is the only method class A has, as that is what you defined. It will print Dog!
}
However, B defines its own method, called cat(). So you can do b.cat().
BUT DON'T FORGET: B also extends A, so what A has, B also has.
So you can also call b.dog()!
obj3 since it is linked to a new B() can call both dog() AND cat().
If they were named the same thing, obj3 would call the version of the method defined in class B.
However, in your case, they are two seperate methods, one is NOT overriding the other.
To answer your question.
If we return to my code, calling
A obj3 = new B();
obj3.doSomething();
// Prints Meow!
This is because we defined obj3 as a new B() so it takes on the method doSomething() in they way class B defines it.
Class A Sample 1
public class A {
private A instance = new A();
public A() {
}
public A getInstance() {
return instance;
}
}
Class A Sample 2
public class A {
private static A instance = new A();
public A() {
}
public static A getInstance() {
return instance;
}
}
Main Class
public class MainClass {
public static void main(String[] args) {
A a = new A();
}
}
When I try to run above program with using Class A Sample 1, it throws stackOverflowError Exception but when I try to run with using Class A Sample 2
it run without any errors. Anyone who can explain to me with details why it throws error when I using Class A sample 1? Thank you.
private A instance = new A();
public A() {
}
This is equivalent to code which calls new A() in the constructor. It's effectively the same as:
private A instance;
public A() {
this.instance = new A();
}
Do you see how this causes infinite recursion? The constructor A() invokes itself.
private static A instance = new A();
On the other hand, when you have a static variable it's only instantiated once when the class itself is loaded, rather than every time an instance of the class is created. It's as if you had done it in a static initialization block—which only runs a single time.
private static A instance;
static {
A.instance = new A();
}
Notice how this.instance has become A.instance. There's only a single class-wide instance variable here versus a per-instance copy in the other version.
Because in the non-static case, you're invoking new A() every time a new A is created...
Sample 1 causes an infinite loop since every time you create an instance of A it will create another instance of A until you run out of stack space. Since you use static in Sample 2 the member variable instance will be created once.