Why it throws stackOverflowError when the getInstance method is not static - java

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.

Related

How do I create only one object of parent and child

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

Java: Manipulating non-static variable from thread?

The relevant summary of my code is this:
public class A {
String aString;
public static void main(String[] args) {
B b = new B();
new Thread(b).start();
}
public static class B implements Runnable {
public void run() {
aString = "foo";
}
}
}
I have had a few months of Java coding experience but thread and dynamic vs. static is still rather new to me. In order for the thread to execute properly, class B must be static, or else only the thread executes, not both. My goal is to obviously have the thread execute in the background so that other code that I may have in class A can execute simultaneously. Problem is, if class B is static, I can't manipulate the string aString, as I get the exception non-static variable aString cannot be referenced from a static context.
I've looked up information on this but I have not found anything that relates to fixing this issue in threads. My question is, how can I manipulate aString within class B and still get the thread to work properly (both classes running, not just class B)?
To make your example work, you'll need something like this:
public class A {
volatile String aString;
public static void main(String[] args) throws InterruptedException {
A a = new A();
Thread t = new Thread(a.new B());
t.start();
t.join(); // wait for t to finish
System.out.println(a.aString); // prints "foo"
}
class B implements Runnable {
public void run() {
aString = "foo";
}
}
}
Resolving the static issue is the easy part - see code for how.
I hope the rest of the code helps illustrate some of the issues you need to cater for when using threads.
B is static, so only only exists at the class level, and can therefore not see instance variables of its parent class
public class A {
String aString; // <== instance variable
public static void main(String[] args) {
B b = new B();
new Thread(b).start();
}
public static class B implements Runnable { // <== static class
public void run() {
aString = "foo";
}
}
}
Possible fix. Make aString static too
public class A {
static String aString;
Possible fix. Make B non-static. This is where it gets a bit weird. B now only exists at the instance level of A, so you need to create an A instance first.
public class A {
String aString;
public static void main(String[] args) {
B b = new A().new B(); // <== need to create an A before a B
new Thread(b).start();
}
public class B implements Runnable {
public void run() {
aString = "foo";
}
}
}
You are asking an object instance of class B (which you create using new B() )to access a member variable of an object instance that you haven't created. In your code, there is no object of class B created.
I think that you may be thinking that running the main() method in class A is somehow instantiating an instance of class A - this is not the case.
The following will work because you are creating an instance of A and making that available to your instance of B.
public class A {
String aString;
public static void main(String[] args) {
A a = new A();
B b = new B(a);
new Thread(b).start();
}
public static class B implements Runnable {
private final A a;
public B(A a){
this.a = a;
}
public void run() {
a.aString = "foo";
}
}
}

Avoid Object Creation in Java

How to stop other classes to create the object of the class using new operator in java. For Example, i have one class A. i don't want any other class to create its object using new operator.
One Approach is that i can throw IllegalArgumentException in the constructor of class A.
is there any other?
public class A{
public A(){
throw IllegalArguementException();
}
}
The approach what you followed is wrong.. you can't create object of your class as well with this approach.
So you must make your construction private and write static method to get the instance of the class.
class Test
{
private Test(){ }
public static Test getTestInstance(){
return new Test();
}
}
Hope it helps,
You can do it by making the constructor private.
class A
{
int i;
private A()
{
i=1;
}
public static A getInstance()
{
return new A();
}
}
class B
{
A a;
public B()
{
/* a=new A(); //This doesn't compile */
}
}
Implementing Singleton in Java 5 or above version using Enum is thread safe and implementation of Singleton through Enum ensures that your singleton will have only one instance even in a multithreaded environment.
public enum SingletonEnum {
INSTANCE;
public void doYourStuff(){
System.out.println("Singleton using Enum");
}
}
And this can be called from clients :
public static void main(String[] args) {
SingletonEnum.INSTANCE.doYourStuff();
}
You can make the class abstract (though in this case no instance of this class can be instantiated by any class, so perhaps it's not what you want), or make the constructor private.
private A() {}
Make the constructor private.

members initializing using "this"

here is my problem
class A{
private B b = new B(this); // line 2
A(){}
}
This is just an ex. code and works fine. But i have a doubt about this is used to current reference (instance of A). Class initializing happens before to get a class instance. So how can we put this in line 2. i asked does instantiation happen before initializing?
You bring up an interesting point. Here is a contrived instructional example that demonstrates a run time problem that can happen when using your example.
class A {
private boolean isInitialized = false;
private final B b = new B(this);
public A() {
initialize();
}
private void initialize() {
isInitialized = true;
}
public boolean isInitialize() {
return isInitialized;
}
public B getB() {
return b;
}
}
class B {
private boolean isInitialized = false;
final private A a;
public B(final A a) {
this.a = a;
initialize();
System.out.println("inB: a.isInitialize()=" + a.isInitialize());
}
private void initialize() {
isInitialized = true;
}
public boolean isInitialize() {
return isInitialized;
}
}
public static void main(final String[] args) {
final A a = new A();
System.out.println("inMain: a.isInitialize()=" + a.isInitialize());
System.out.println("inMain:a.getB().isInitialize()=" + a.getB().isInitialize());
}
Output:
inB: a.isInitialize()=false
inMain: a.isInitialize()=true
inMain:a.getB().isInitialize()=true
Using the passed reference to class A within class B runs the real risk of using an object that is not fully initialized.
Be careful.
This is not class initialization (try to debug new ClassA() step by step), it is actually instance initialization.
There can be some problems if the constructor (from ClassB) calls some functions from ClassA, which access some fields in ClassA that are not initialized.
Edit: this is done before the constructor is called.
this is used correctly. The constructor doesn't need to be called at all.
No need for changes, everything is fine. this is a valid reference to A.
this will show its existence when you create an object of class A. Instance variable are assigned after object creation and static variable are initialize as soon as class loads and also before creations of any object.
you cannot use above initialization in static block
static {
private B b = new B(this); // compiler error. you cannot use 'this' in static context.
}

How to avoid the creation of object in Java?

I am new to java programming,I have one class,for this class i created two object(obj1,obj2).i don't want to create other than these object,if any body wants to create one more object for this class that should refer to first,or second objects only(instead of creating one more object).how to do this?please refer below code
class B
{
void mymethod()
{
System.out.println("B class method");
}
}
class Myclass extends B
{
public static void main(String s[])
{
B obj1=new B();//this is obj1
B obj2=new B();//this is obj1
B obj3=new B();//don't allow to create this and refer this to obj1 or obj2
}
}
Thanks
azam
Check out the Singleton design pattern.
What you need is the Singleton design pattern.
Class B should look something like so:
class B
{
private static B instance = null;
private B()
{
//Do any other initialization here
}
public static B getInstance()
{
if (instance == null)
{
instance = new B();
}
return instance;
}
}
Then, in your Myclass, just do this:
B obj1 = B.getInstance();
B obj2 = B.getInstance();
Note: This is not thread safe. If you are looking for a thread safe solution please consult the Wiki Page.
EDIT: You could also have a static initializer
class B
{
private static B instance = null;
static
{
instance = new B();
}
private B()
{
//Do any other initialization here
}
public static B getInstance()
{
return instance;
}
}
Yeah singleton it seems the correct way consider the info your providing here.
The default singleton implementation would be the following:
public class Singleton {
//holds single instance reference
private static Singleton instance = null;
//private constructor to avoid clients to call new on it
private Singleton()
{}
public static Singleton getInstance()
{
if(null == instance)
{
instance = new Singleton();
}
return instance;
}
}
Now you can get the single instance of the object by calling :
Singleton instance = Singleton.getInstance();
Keep in mind though that if your working on a threaded enviroment, singleton by default is not thread-safe.
You should make the getInstance method synchronized to avoid unexpected returns.
public synchronized static Singleton getInstance()
{
if(null == instance)
{
instance = new Singleton();
}
return instance;
}
Cheers
Generally speaking you need a singleton pattern. You need to make the constructor to become a private method. Then you create a method to instantiate class B, hence class B can only be instantiated by this method. Have a look at the singleton pattern. It is what you want I believe.
create singleton Class, like
public Class A {
private static Class a = new A();
public A getA() {
return a;
}
}
Object of class A has already created in class A itself. You don't need to create it outside. Just use getA() method to retieve the class A's object.
Like :
A objA = A.getA();
This is called Singlton Pattern.
You can use a Singleton. You have 2 possiblilities for that.
1 . Lazy Creation (Here you make the instance when call the function getInstance() and you check if the instance already exists):
class B {
static private B instance;
private void mymethod() {
System.out.println("B class method");
}
static public B getInstance() {
if (instance == null) {
instance = new B();
}
return instance;
}
}
class Myclass extends B {
public static void main(String s[]) {
B obj1 = B.getInstance(); // this is obj1
B obj2 = B.getInstance();
}
}
2 . Eager creation (Here you make the instance when the Class is called for the first time):
class B {
static private B instance = new B();
private void mymethod() {
System.out.println("B class method");
}
static public B getInstance() {
return instance;
}
}
class Myclass extends B {
public static void main(String s[]) {
B obj1 = B.getInstance(); // this is obj1
B obj2 = B.getInstance();
}
}
be aware, that using a singleton is a big restriction to your code. It can be very annoying when it's not possible to instance more than one object.
Especially when you dont have acces to the source....
The Effective way in multi threaded application, the below logic will may help
public class Singleton {
private static volatile Singleton _instance;
private Singleton(){}
public static Singleton getInstance() {
if (_instance == null) {
synchronized (Singleton.class) {
if (_instance == null)
_instance = new Singleton();
}
}
return _instance;
}
}
I suppose people have not understood the problem statement. It says, not more than 2 objects shall be created. Singleton creates a single object and blocks any further instantiation.
maintain a static variable in ur object class, incrementing by 1 to the upper limit of objects while creating object
when object > bounds needs to be created, select a random number in range[1,bound] and return that object.

Categories