Is it possible to refer to an object in its constructor?

Can I do the following?

public Manager(String userName) { game = new Game(userName); game.addManager(this); } 

The problem is that I am referencing the ( this ) object in its constructor (before its actual creation).

+4
source share
7 answers

Although this is legal Java, and in the case where you are describing (where is the last line of the constructor), this is a pretty safe thing (with some exceptions in the case of an exception), since practice is a bad thing to do, and like using goto (in languages ​​that support keyword) it should be something you think long and hard about. For your case, it would be best practice to make the constructor private, remove the addManager call, and set the static factory method:

  public static Manager createManager(String userName) { Manager manager = new Manager(userName); manager.game.addManager(manager); return manager; } 

I should also point out that such interdependence between classes (the manager knows about the game and the game knows about the manager) is certainly a smell of code, and I would be just as concerned about the need for this as I would to pass this from the constructor.

+4
source

Yes, you can do it, but you shouldn't do it .

The problem is that posting this while the constructor is still working can create all kinds of strange side effects, since some general guarantees are not fulfilled while the constructor is still working (e.g. final variables may seem to change their value while the constructor is still works).

This IBM developerWorks article describes the precautions for creating objects and the rationale for these precautions. Although the article discusses the topic in light of multithreading, you can have similar problems in a single-threaded environment when unknown / untrusted code gets a link to this at build time.

(the last paragraph was "stolen" from one of my earlier answers ).

+3
source

Yup its excellent legal in Java, however not recommended. See here for more details on this key.

+2
source

As @James said you can, but this is not necessarily what you want to do. If game.addManager trying to access certain Manager properties, you can try to access Manager properties that have not yet been initialized. The best approach is for the external object to call some init method (or some lifecycle method) to add the manager and not execute it in the constructor.

+1
source

See if this helps, this is actually for c / C ++, but I think it is the same for java:

http://www.gotw.ca/publications/mill13.htm

0
source

This method violates one of the concepts of java concurrency - secure publishing. You must use the init() method for this purpose or another method.

You see, you can initialize some final fields in your constructor (or perform some other initialization) after this link has been removed. If you pass an instance of your object into your constructor to another object, then you can get a callback at build time. And this can lead to inconsistent behavior, NPE, dead locks, etc.

0
source

Boy, this is not safe! Although the correct code, but not a good design! Your code allows "this" to refer to escape before the object is properly constructed.

Imagine that game.addManager () will reference some xxx () method with the "this" link. And we have a subclass of Manager, ChildManager, which overrides the xxx () method, and this method depends on the field in ChildManager (which does not initialize when the superconstructor reaches its last line of code). Game.addManager () will see the uninitialized field value in ChildManager, which is very dangerous!

Code example:

  public class Manager { Game game; public Manager (String userName){ game = new Game(userName); game.addManager(this); } public void xxx(){ } } public class ChildManager extends Manager { String name; public ChildManager (String username){ super(username); name = username; } public void xxx (){ System.out.println(name); } } public class Game { public Game (String userName){ } public void addManager (Manager m){ m.xxx(); } } 
0
source

Source: https://habr.com/ru/post/1307551/


All Articles