score:10
What happens in init()
? It's likely that a better design could eliminate the method altogether, or at least relax the requirement that it execute after the sub-class' constructor. Be certain that init()
does not make the object under construction visible to any other threads before the constructor completes, because that creates concurrency bugs.
As an (ugly) alternative, an abstract method could be implemented by sub-classes as a pseudo-constructor:
abstract class Base {
Base() {
ctor();
init();
}
abstract void ctor();
abstract void init();
}
score:1
Or use spring... you can do <beans default-init-method="init">
, see Default initialization and destroy methods.
score:1
If you are adverse to using factories for some reason, you could use the following trick:
trait RunInit {
def init():Unit
init()
}
class Derived1 extends Base with RunInit {
def init() = println("INIT'ing!")
}
This will run init() before the Derived1 constructor/body.
score:2
if Java had it, we wouldn't see all these init() method calls in the wild.
"surround child constructor with something" - that cannot be done in pure java. Too bad, because there can be very interesting applications, especially with anonymous class + instance initialization block.
factory and container - they can be helpful when native new
doesn't do the job; but that's trivial and boring, and won't work with anonymous classes.
score:6
In addition to Bozho's recommendation, an application container is excellent for the task.
Mark your init()
method with the javax.annotation.PostConstruct
annotation and a rightly configured EJB or Spring container will execute the method after the dependency injections are finished, but before the object can be used by the application.
An example method:
@PostConstruct
public void init() {
// logic..
}
In an enterprise application you can open resources to for example the files system in the init()
method. This initialization can throw exceptions and should not be called from a constructor.
score:12
Avoid this. If you do it, any class that extends your DerivedX
class may decide to also call init()
thus leaving the object in inconsistent state.
One approach is to let the init()
method be invoked manually by clients of your class. Have an initialized
field, and throw IllegalStateExcepion
if any method that requires initialization is called without it.
A better approach would be to use a static factory method instead of constructors:
public Derived2 extends Base {
public static Derived2 create() {
Derived2 instance = new Dervied2();
instance.init();
return instance;
}
}
Update: As you suggest in your update, you can pass Builder to a static factory method, which will call the init()
on the instance. If your subclasses are few, I think this is an overcomplication, though.
Source: stackoverflow.com
Related Query
- Running a method after the constructor of any derived class
- If the Nothing type is at the bottom of the class hierarchy, why can I not call any conceivable method on it?
- Using trait method in the class constructor
- Scala compiler error due to constructor parameter (property) having same name in both base and derived class and used in derived method
- Error in running Scala Program: Main method not found in class main, please define the main method
- Scala case class private constructor but public apply method
- Why can't a class extend traits with method of the same signature?
- How do I declare a constructor for an 'object' class type in Scala? I.e., a one time operation for the singleton
- Scala: what is the real difference between fields in a class and parameters in the constructor
- Instantiate a Scala class from Java, and use the default parameters of the constructor
- Case class constructor argument type depending on the previous argument value
- How to create a Scala class with private field with public getter, and primary constructor taking a parameter of the same name
- How can I syntax check a Scala script without executing the script and generating any class files?
- Does extending a class in scala with constructor params add vals (fields) to the class?
- Performance drop after 5 days running web application, how to spot the bottleneck?
- protected method that takes an abstract super class instance and the "access to protected method not permitted" error
- Invoking a Future inside a receive method and stopping the actor after that
- Implicit conversions in the context of a (case) class constructor
- A class imported from a companion not usable as the constructor parameter default value
- How to read the class of a Scala object extending Any but not AnyRef?
- What happens to a variable assignment when I call a method that returns an instance of a case class holding the said variable?
- Class constructor declaration... Two ways of declaring the same thing?
- Move the implementation of a generic method to an abstract super class
- Why does running javap on a compiled Scala class show weird entries in the constant pool?
- Scala what is the difference between defining a method in the class instead on the companion object
- What is the idiomatic way to extend a class which has implicit parameters in the constructor in Scala?
- scala: How to get the class in its own constructor
- Running Scala tests automatically either after test change or tested class change
- Derived classes as class constructor parameters
- Why can method parameter F have the same name as type constructor F?
More Query from same tag
- Embedding multiple tests inside an akka-http route check
- Accessing type-parameter of a type-parameter
- How to count occurrences of different values in multiple columns all at once where number or name of columns is not known?
- Changing implicit variable from private to public cause 'covariant type T occurs in invariant position' Error
- Scala Slick Class Table Definition, Error Declaring DateTime columns
- Apache Spark: I always got org.apache.axis.AxisFault: (404)Not Found when using google-spark-adwords
- sbt.IncompatiblePluginsException: Binary incompatibility in plugins detected
- Scala replaceAllIn not working correctly?
- Spark streaming connection to S3 gives Forbidden error
- jpa/scala no persistence provider named yyy?
- LabelledGenerid.Aux implicit not available when using generic type in function body
- How to get sum of product from columns in 2 data frame using PySpark
- Strip Javascript Comments in Java/Scala Program
- Reuse java connectionpool in scala
- Play framework read from json list
- Spark Select with a List of Columns Scala
- Confused by "...extends Function1[Int, Int]"
- Write function with type parameter
- How to pattern-match an `Option` in the underlying?
- Scala - Which is the most efficient way to get the names of the null columns from spark dataframe?
- Convert java enum to scala Enumeration for json4s serialization
- A useful metric for determining when the JVM is about to get into memory/GC trouble
- Squeryl: KeyedEntity.id isn't updated on insert
- How to display mismatched report with a label in spark 1.6 - scala except function?
- Scala key/value case class to Json
- CountDistinct based on a condition in spark scala
- Using reflection to override 2 + 2 = 5
- How to map spark DataFrame row values to columns?
- How to enable scala linter?
- Introducing termination as a precondition in Stainless