Say, I have a package Pack containing classes A and B. A is self-contained and no one (even in the Pack) should see A's insides, so most of the fields and methods are private.
Now I want to extend A to change one of its private methods keeping the rest - let it be class AMod. Doing it requires most of A's fields and the method to override to be protected, but protected gives access to the package.
So how do I create AMod inside Pack so that AMod has an access to A's fields and methods while no one else does? Make a nested/separate package?
UPD:
UPD2:
UPD3:
As Jacob G. suggested, my code needed redesigning, and I managed to remove the derived class from the architecture. Thanks for help!
The one answer I find missing: don't be so focused on using inheritance in order to avoid code duplication.
If you only need a subtle variation of behavior of A then you should first consider to "wrap" around A (for example via decorator) instead of extending A - the good old FCoI!
If that isn't possible: have a very close look at the common behavior of A and Amod and extract those parts in a common base class.
Finally: don't get too energetic about java access modifiers in the first place. In the end, they help you to communicate a certain thought or idea. "Evil-willing" people will always find a way to work around your intentions. What I am saying is: if you are concerned that your team members use your class in the wrong way ... that is a social problem; and you will never be able to solve that on the technical layer. You have to solve it on the social layer, too (by educating people to ensure that they understand what to do; instead of hoping that private here or protected there will prevent them from doing the wrong thing).
In other words: establish a simple policy such as "only what is marked public is meant to be public; anything else is not" might be able to table such discussions for all times. Versus spending hours and hours to find a perfect private-protected solution within source code.
Thanks for posting code.
My advice would be to first move B#stepBMod into A.java. Then, you can pass a boolean parameter to A#build; with this, you can rewrite A#build:
public Result build(boolean mod) {
stepA();
if (mod) {
stepBMod();
} else {
stepB();
}
stepC();
return result;
}
Now, B.java isn't needed anymore.
Your question is two parts. 1)Accessing fields and 2)Accessing methods.
Case1), you should make class A's fields protected. This means no one can access it by name, except derived classes.
Case2), you cannot access a protected method by name, unless in a derived class. But still you can access a protected method by name using an object of A. In order to prevent other classes making objects, your A class should be abstract.
Here is an example
public abstract class A{
protected int n;
protected void display(){
System.out.println(n);
}
}
public class B extends A{
public void demo(){
B object = new B();
object.display();
}
public void modify(){
n = 0;
}
}
Update
class A
{
public A(Args args){...}
public Result build() {
stepA();
stepB();
stepC();
return result;
}
protected void stepA() {...}
private void stepB() {...}
protected void stepC() {...}
protected T field;
}
class AMod extends A
{
public AMod(Args args){
super(args);
...
}
public Result build() {
stepA();
stepBMod();
stepC();
return result;
}
private void stepBMod() {...}
}
Related
In Java: What is the best way to pass a method from one object to another so that it can be called at a later time by the second object?
I come from an ActionScript background where it is as easy to pass around references to methods as it is to pass around references to variables but this seems to be much more difficult in Java. The first few links I found flat out say it is not possible (and it may have been at the time of their posting), but then I found http://www.javacamp.org/javavscsharp/delegate.html which details how this can be accomplished.
My issue with using Javacamp's example is the string based reference to the method. Methods get renamed all the time and a string reference will only complain once you actually run that function runtime as opposed to compile time for a proper explicit link.
Is there no way to do this with proper explicit links to the method you want the other class to execute?
Model of what I am hoping to accomplish:
Player clicks an upgrade button on Activity1 > Activity1 passes upgrade method to a new confirmation activity
Player clicks "Yes" > Confirmation activity calls upgrade method passed in from Activity1
OR: Player clicks "No" > Confirmation Activity closes
EDIT:
To be clear I am not looking for a static method solution as that would require my Confirmation activity to hold many lines of logic for which static method to call. The Confirmation activity will be used all over my application: a simple "Are you sure you want to X?" -Yes -No, if yes execute X
I am currently looking at implementing onActivityResult to avoid this issue but that will be more logic than I like for this kind of issue.
you can use interfaces like this:
public interface MyMethod {
public void method();
}
public class FirtObject{
private SecondObject ob;
public void tellSecondObjectExecuteLater(){
ob.executeLater( new MyMethod() {
public void method(){System.out.println("duh Method");} });
}
}
public class SecondObject {
private MyMethod myMth;
public void executeLater(MyMethod mth){
myMth = mth;
}
public void executeNow(){
myMth.method();
}
}
does this solve your problem?
The typical way to pass methods is to use an Interface and Anonymous Inner Classes. In order to maintain static typing an Interface is used to declare the method signature and typing information. The caller can use either a concrete implementation of that interface as a normal class or using Anonymous Inner Classes for quick class creation. I'll use standard Java SDK classes to illustrate:
interface Comparator<T> {
public int compare( T a, T b);
}
class SpecialCollection<T> {
public void sort( Comparator<T> comparator ) {...}
}
public class SomeClient {
public void doSomething( SpecialCollection<SpecialObj> collection ) {
collection.sort( new Comparator<SpecialObj>() {
public int compare( SpecialObject a, SpecialObject b ) {
// some implementation
}
} );
}
}
The above is an example of a strategy pattern. The thing about the strategy pattern (and passing callback methods like in Javascript). The author has to plan for those types of extensions. The author has to predict up front where he/she wants you to extend. And it just happens it's cleanest if you use Interfaces.
However, pure delegation doesn't have to have always involve Interfaces. You can pass concrete classes, since Java can always pass a subclass that overrides various methods of that class to change what method or code will be invoked. For example in Java InputStream/OutputStream are abstract classes and you typically pass subclass instances to the methods.
If you need the method to act differently depending on the context (AKA, it is different depending on how it is created), you'll want to pass along the instance of the class that the method is in.
If it is a static method, you can just referenced the method itself if you import that class at the top of your new class.
For example, lets say you have a method that will tell you stuff about a certain string. IF the class looks like this:
class stringChecker {
private String stringToCheck;
public class stringChecker(String s) {
stringToCheck = s;
}
public int getStringLength() {
return stringToCheck.length();
}
public boolean stringStartsWith(String startsWith) {
return (stringToCheck.indexOf(startsWith) == 0);
}
}
Then you'll want to pass along the instance, since it is non-static. Different instances have different strings that they were created with, so you will get a different return if you use a different instance.
However, if your class looks more like this:
class stringChecker {
public static int getStringLength(String s) {
return s.length();
}
public static boolean stringStartsWith(String s, String startsWith) {
return (s.indexOf(startsWith) == 0);
}
}
Then you can just reference those methods with stringChecker.getStringLength("test");, because the methods are static. It doesn't matter what instance they are in. The returned result depends ONLY on what is being passed in. You just have to make sure to add import stringChecker; at the top or whatever your class will be called. For you, it'll probably be something like com.example.blah.otherthing.stringChecker, since you're working with android.
Good luck! I hope this helps :)
EDIT: Looks like I may have read the problem too quickly...if this isn't what you were asking about, just let me know with a comment and I'll delete this answer so as to not confuse anybody else.
You said that you are using it in a project to open a Confirmation activity.
Activities should not contain references to each other to avoid memory leaks. To pass data between activities should be used Intent class. To receive a result, call StartActivityForResult() and get result in the onActivityResult() method.
But in general for your task is more suitable AlertDialog or PopupWindow.
I have the following classes
class Person {
private String name;
void getName(){...}}
class Student extends Person{
String class;
void getClass(){...}
}
class Teacher extends Person{
String experience;
void getExperience(){...}
}
This is just a simplified version of my actual schema. Initially I don't know the type of person that needs to be created, so the function that handles the creation of these objects takes the general Person object as a parameter.
void calculate(Person p){...}
Now I want to access the methods of the child classes using this parent class object. I also need to access parent class methods from time to time so I CANNOT MAKE IT ABSTRACT.
I guess I simplified too much in the above example, so here goes , this is the actual structure.
class Question {
// private attributes
:
private QuestionOption option;
// getters and setters for private attributes
:
public QuestionOption getOption(){...}
}
class QuestionOption{
....
}
class ChoiceQuestionOption extends QuestionOption{
private boolean allowMultiple;
public boolean getMultiple(){...}
}
class Survey{
void renderSurvey(Question q) {
/*
Depending on the type of question (choice, dropdwn or other, I have to render
the question on the UI. The class that calls this doesnt have compile time
knowledge of the type of question that is going to be rendered. Each question
type has its own rendering function. If this is for choice , I need to access
its functions using q.
*/
if(q.getOption().getMultiple())
{...}
}
}
The if statement says "cannot find getMultiple for QuestionOption." OuestionOption has many more child classes that have different types of methods that are not common among the children (getMultiple is not common among the children)
NOTE: Though this is possible, it is not at all recommended as it kind of destroys the reason for inheritance. The best way would be to restructure your application design so that there are NO parent to child dependencies. A parent should not ever need to know its children or their capabilities.
However.. you should be able to do it like:
void calculate(Person p) {
((Student)p).method();
}
a safe way would be:
void calculate(Person p) {
if(p instanceof Student) ((Student)p).method();
}
A parent class should not have knowledge of child classes. You can implement a method calculate() and override it in every subclass:
class Person {
String name;
void getName(){...}
void calculate();
}
and then
class Student extends Person{
String class;
void getClass(){...}
#Override
void calculate() {
// do something with a Student
}
}
and
class Teacher extends Person{
String experience;
void getExperience(){...}
#Override
void calculate() {
// do something with a Teacher
}
}
By the way. Your statement about abstract classes is confusing. You can call methods defined in an abstract class, but of course only of instances of subclasses.
In your example you can make Person abstract and the use getName() on instanced of Student and Teacher.
Many of the answers here are suggesting implementing variant types using "Classical Object-Oriented Decomposition". That is, anything which might be needed on one of the variants has to be declared at the base of the hierarchy. I submit that this is a type-safe, but often very bad, approach. You either end up exposing all internal properties of all the different variants (most of which are "invalid" for each particular variant) or you end up cluttering the API of the hierarchy with tons of procedural methods (which means you have to recompile every time a new procedure is dreamed up).
I hesitate to do this, but here is a shameless plug for a blog post I wrote that outlines about 8 ways to do variant types in Java. They all suck, because Java sucks at variant types. So far the only JVM language that gets it right is Scala.
http://jazzjuice.blogspot.com/2010/10/6-things-i-hate-about-java-or-scala-is.html
The Scala creators actually wrote a paper about three of the eight ways. If I can track it down, I'll update this answer with a link.
UPDATE: found it here.
Why don't you just write an empty method in Person and override it in the children classes? And call it, when it needs to be:
void caluculate(Person p){
p.dotheCalculate();
}
This would mean you have to have the same method in both children classes, but i don't see why this would be a problem at all.
I had the same situation and I found a way around with a bit of engineering as follows - -
You have to have your method in parent class without any parameter and use - -
Class<? extends Person> cl = this.getClass(); // inside parent class
Now, with 'cl' you can access all child class fields with their name and initialized values by using - -
cl.getDeclaredFields(); cl.getField("myfield"); // and many more
In this situation your 'this' pointer will reference your child class object if you are calling parent method through your child class object.
Another thing you might need to use is Object obj = cl.newInstance();
Let me know if still you got stucked somewhere.
class Car extends Vehicle {
protected int numberOfSeats = 1;
public int getNumberOfSeats() {
return this.numberOfSeats;
}
public void printNumberOfSeats() {
// return this.numberOfSeats;
System.out.println(numberOfSeats);
}
}
//Parent class
class Vehicle {
protected String licensePlate = null;
public void setLicensePlate(String license) {
this.licensePlate = license;
System.out.println(licensePlate);
}
public static void main(String []args) {
Vehicle c = new Vehicle();
c.setLicensePlate("LASKF12341");
//Used downcasting to call the child method from the parent class.
//Downcasting = It’s the casting from a superclass to a subclass.
Vehicle d = new Car();
((Car) d).printNumberOfSeats();
}
}
One possible solution can be
class Survey{
void renderSurvey(Question q) {
/*
Depending on the type of question (choice, dropdwn or other, I have to render
the question on the UI. The class that calls this doesnt have compile time
knowledge of the type of question that is going to be rendered. Each question
type has its own rendering function. If this is for choice , I need to access
its functions using q.
*/
if(q.getOption() instanceof ChoiceQuestionOption)
{
ChoiceQuestionOption choiceQuestion = (ChoiceQuestionOption)q.getOption();
boolean result = choiceQuestion.getMultiple();
//do something with result......
}
}
}
Here is my question :
I have a huge class (HugeClass) and I wanted to split it into several little classes (LittleClass1, LittleClass2, ...). I heard about delegation. It sounds good, but I think it cannot works in my case.
Indeed, my little classes need some of the attributes of HugeClass:
public class HugeClass
{
// Attributes
private Object object1;
private Object object2;
private Object object3;
...
private Object objectN;
// Delegation 1
private LittleClass1 little1 = new LittleClass1 ();
// Function delegated in the LittleClass1
public void delegated1 ()
{
little1.delegated1 ();
}
}
Here an example of a Delegation class :
public class LittleClass1
{
public LittleClass1 ()
{
}
public void delegated1 ()
{
// Here, I need object1, object3, and more to work !
}
}
The number of attributes needed by the delegated1 function can be large. So I think using the constructor of LittleClass1 is not very convenient.
And because LittleClass1 override only one method of HugeClass, I don't think that LittleClass1 should extends HugeClass.
Do you have an idea of a solution ? Using another pattern ?
Thanks !
Update
Delegated functions might need not only instance variables, but also instance functions :
public class LittleClass2
{
public LittleClass2 ()
{
}
public void delegated2 ()
{
// I need object2 and delegated1 to work !
}
}
Giving HugeClass to the constructor might solve this problem. But is this a good solution ?
Breaking up a huge class into smaller classes is generally good to improve the maintainability, testability and overall quality of the code. The smaller chunks should be easier to reason about in isolation. What you want is to look for semantically distinct features of the huge class, and split them apart, first by extracting methods, and then by extracting classes. You're not necessarily looking for a pattern, as much as looking for refactoring techniques, like the ones in the books Refactoring and Working Effectively with Legacy Code.
Now, if your little classes seem to share too many of the instance variables of the huge class, maybe you should take a step back and start with some low hanging fruits, like code that doesn't depend on too many variables; or try to find a grouping of those variables that semantically make sense to be encapsulated in a new object, what would decrease the number of these free variables and increase the quality of the design, as finding the latent concepts in the design make the code more explicit and understandable.
UPDATE: by the way, inheritance is really not a good idea. You want to decouple the concerns, and inheritance is just another more subtle way of coupling.
Looks like you just need LittleClass1 to subclass HugeClass, and its fields protected:
public abstract class HugeClass {
// Attributes - now protected instead of private
protected Object object1;
protected Object object2;
protected Object object3;
...
protected Object objectN;
-- Note: No delegation, no reference to LittleClass1 here
public abstract void delegated ()
}
public class LittleClass1 extends HugeClass {
public void delegated () {
// Here, you have access to object1, object2 etc
}
}
Introduction
As a disclaimer, I'v read Why can't static methods be abstract in Java and, even if I respectfully disagree with the accepted answer about a "logical contradiction", I don't want any answer about the usefulness of static abstract just an answer to my question ;)
I have a class hierarchy representing some tables from a database. Each class inherits the Entity class which contains a lot of utility methods for accessing the database, creating queries, escaping characters, etc.
Each instance of a class is a row from the database.
The problem
Now, in order to factorize as much code as possible, I want to add information about related columns and table name for each class. These informations must be accessible without a class instance and will be used in Entity to build queries among other things.
The obvious way to store these data are static fields returned by static methods in each class. Problem is you can't force the class to implement these static methods and you can't do dynamic linking on static methods call in Java.
My Solutions
Use a HashMap, or any similar data structure, to hold the informations. Problem : if informations are missing error will be at runtime not compile time.
Use a parallel class hierarchy for the utility function where each corresponding class can be instantiated and dynamic linking used. Problem : code heavy, runtime error if the class don't exist
The question
How will you cope with the absence of abstract static and dynamic linking on abstract method ?
In a perfect world, the given solution should generate a compile error if the informations for a class are missing and data should be easily accessible from withing the Entity class.
The answer doesn't need to be in Java, C# is also ok and any insight on how to do this without some specific code in any language will be welcomed.
Just to be clear, I don't have any requirement at all besides simplicity. Nothing have to be static. I only want to retrieve table and columns name from Entity to build a query.
Some code
class Entity {
public static function afunction(Class clazz) { // this parameter is an option
// here I need to have access to table name of any children of Entity
}
}
class A extends Entity {
static String table = "a";
}
class B extends Entity {
static String table = "b";
}
You should use the Java annotation coupled with the javac annotation processor, as it's the most efficient solution. It's however a bit more complicated than the usual annotation paradigm.
This link shows you how you can implement an annotation processor that will be used at the compile time.
If I reuse your example, I'd go this way:
#Target(ElementType.TYPE)
#Retention(RetentionType.SOURCE)
#interface MetaData {
String table();
}
abstract class Entity {}
#MetaData(table="a")
class A extends Entity {}
#MetaData(table="b")
class B extends Entity {}
class EntityGetter {
public <E extends Entity> E getEntity(Class<E> type) {
MetaData metaData = type.getAnnotation(MetaData.class);
if (metaData == null) {
throw new Error("Should have been compiled with the preprocessor.");
// Yes, do throw an Error. It's a compile-time error, not a simple exceptional condition.
}
String table = metaData.table();
// do whatever you need.
}
}
In your annotation processing, you then should check whether the annotation is set, whether the values are correct, and make the compilation fail.
The complete documentation is available in the documentation for the package javax.annotation.processing.
Also, a few tutorials are available on the Internet if you search for "java annotation processing".
I will not go deeper in the subject as I never used the technology myself before.
I have run into the same problems as you, and am using the following approach now. Store Metadata about columns as annotations and parse them at runtime. Store this information in a map. If you really want compile time errors to appear, most IDEs (Eclipse e.g.) support custom builder types, that can validate the classes during build time.
You could also use the compile time annotation processing tool which comes with java, which can also be integrated into the IDE builds. Read into it and give it a try.
In Java the most similar approach to "static classes" are the static enums.
The enum elements are handed as static constants, so they can be accesed from any static context.
The enum can define one or more private constructors, accepting some intialization parameters (as it could be a table name, a set of columns, etc).
The enum class can define abstract methods, which must be implemented by the concrete elements, in order to compile.
public enum EntityMetadata {
TABLE_A("TableA", new String[]{"ID", "DESC"}) {
#Override
public void doSomethingWeirdAndExclusive() {
Logger.getLogger(getTableName()).info("I'm positively TableA Metadata");
}
},
TABLE_B("TableB", new String[]{"ID", "AMOUNT", "CURRENCY"}) {
#Override
public void doSomethingWeirdAndExclusive() {
Logger.getLogger(getTableName()).info("FOO BAR message, or whatever");
}
};
private String tableName;
private String[] columnNames;
private EntityMetadata(String aTableName, String[] someColumnNames) {
tableName=aTableName;
columnNames=someColumnNames;
}
public String getTableName() {
return tableName;
}
public String[] getColumnNames() {
return columnNames;
}
public abstract void doSomethingWeirdAndExclusive();
}
Then to access a concrete entity metadata this would be enough:
EntityMetadata.TABLE_B.doSomethingWeirdAndExclusive();
You could also reference them from an Entity implemetation, forcing each to refer an EntityMetadata element:
abstract class Entity {
public abstract EntityMetadata getMetadata();
}
class A extends Entity {
public EntityMetadata getMetadata() {
return EntityMetadata.TABLE_A;
}
}
class B extends Entity {
public EntityMetadata getMetadata() {
return EntityMetadata.TABLE_B;
}
}
IMO, this approach will be fast and light-weight.
The dark side of it is that if your enum type needs to be really complex, with lot of different params, or a few different complex overriden methods, the source code for the enum can become a little messy.
Mi idea, is to skip the tables stuff, and relate to the "There are not abstract static methods". Use "pseudo-abstract-static" methods.
First define an exception that will ocurr when an abstract static method is executed:
public class StaticAbstractCallException extends Exception {
StaticAbstractCallException (String strMessage){
super(strMessage);
}
public String toString(){
return "StaticAbstractCallException";
}
} // class
An "abstract" method means it will be overriden in subclasses, so you may want to define a base class, with static methods that are suppouse to be "abstract".
abstract class MyDynamicDevice {
public static void start() {
throw new StaticAbstractCallException("MyDynamicDevice.start()");
}
public static void doSomething() {
throw new StaticAbstractCallException("MyDynamicDevice.doSomething()");
}
public static void finish() {
throw new StaticAbstractCallException("MyDynamicDevice.finish()");
}
// other "abstract" static methods
} // class
...
And finally, define the subclasses that override the "pseudo-abstract" methods.
class myPrinterBrandDevice extends MyDynamicDevice {
public static void start() {
// override MyStaticLibrary.start()
}
/*
// ops, we forgot to override this method !!!
public static void doSomething() {
// ...
}
*/
public static void finish() {
// override MyStaticLibrary.finish()
}
// other abstract static methods
} // class
When the static myStringLibrary doSomething is called, an exception will be generated.
I do know of a solution providing all you want, but it's a huge hack I wouldn't want in my own code nowadays:
If Entity may be abstract, simply add your methods providing the meta data to that base class and declare them abstract.
Otherwise create an interface, with methods providing all your data like this
public interface EntityMetaData{
public String getTableName();
...
}
All subclasses of Entity would have to implement this interface though.
Now your problem is to call these methods from your static utility method, since you don't have an instance there. So you need to create an instance. Using Class.newInstance() is not feasable, since you'd need a nullary constructor, and there might be expensive initialization or initialization with side-effects happening in the constructor, you don't want to trigger.
The hack I propose is to use Objenesis to instantiate your Class. This library allows instatiating any class, without calling the constructor. There's no need for a nullary constructor either. They do this with some huge hacks internally, which are adapted for all major JVMs.
So your code would look like this:
public static function afunction(Class clazz) {
Objenesis objenesis = new ObjenesisStd();
ObjectInstantiator instantiator = objenesis.getInstantiatorOf(clazz);
Entity entity = (Entity)instantiator.newInstance();
// use it
String tableName = entity.getTableName();
...
}
Obviously you should cache your instances using a Map<Class,Entity>, which reduces the runtime cost to practically nothing (a single lookup in your caching map).
I am using Objenesis in one project of my own, where it enabled me to create a beautiful, fluent API. That was such a big win for me, that I put up with this hack. So I can tell you, that it really works. I used my library in many environments with many different JVM versions.
But this is not good design! I advise against using such a hack, even if it works for now, it might stop in the next JVM. And then you'll have to pray for an update of Objenesis...
If I were you, I'd rethink my design leading to the whole requirement. Or give up compile time checking and use annotations.
Your requirement to have static method doesn't leave much space for clean solution. One of the possible ways is to mix static and dynamic, and lose some CPU for a price of saving on RAM:
class Entity {
private static final ConcurrentMap<Class, EntityMetadata> metadataMap = new ...;
Entity(EntityMetadata entityMetadata) {
metadataMap.putIfAbsent(getClass(), entityMetadata);
}
public static EntityMetadata getMetadata(Class clazz) {
return metadataMap.get(clazz);
}
}
The way I would like more would be to waste a reference but have it dynamic:
class Entity {
protected final EntityMetadata entityMetadata;
public Entity(EntityMetadata entityMetadata) {
this.entityMetadata=entityMetadata;
}
}
class A extends Entity {
static {
MetadataFactory.setMetadataFor(A.class, ...);
}
public A() {
super(MetadataFactory.getMetadataFor(A.class));
}
}
class MetadataFactory {
public static EntityMetadata getMetadataFor(Class clazz) {
return ...;
}
public static void setMetadataFor(Class clazz, EntityMetadata metadata) {
...;
}
}
You could get even get rid of EntityMetadata in Entity completely and leave it factory only. Yes, it would not force to provide it for each class in compile-time, but you can easily enforce that in the runtime. Compile-time errors are great but they aren't holy cows after all as you'd always get an error immediately if a class hasn't provided a relevant metadata part.
I would have abstracted away all meta data for the entities (table names, column names) to a service not known by the entities them selfs. Would be much cleaner than having that information inside the entities
MetaData md = metadataProvider.GetMetaData<T>();
String tableName = md.getTableName();
First, let me tell you I agree with you I would like to have a way to enforce static method to be present in classes.
As a solution you can "extend" compile time by using a custom ANT task that checks for the presence of such methods, and get error in compilation time. Of course it won't help you inside you IDE, but you can use a customizable static code analyzer like PMD and create a custom rule to check for the same thing.
And there you java compile (well, almost compile) and edit time error checking.
The dynamic linking emulation...well, this is harder. I'm not sure I understand what you mean. Can you write an example of what you expect to happen?
I have a Wicket page class that sets the page title depending on the result of an abstract method.
public abstract class BasicPage extends WebPage {
public BasicPage() {
add(new Label("title", getTitle()));
}
protected abstract String getTitle();
}
NetBeans warns me with the message "Overridable method call in constructor", but what should be wrong with it? The only alternative I can imagine is to pass the results of otherwise abstract methods to the super constructor in subclasses. But that could be hard to read with many parameters.
On invoking overridable method from constructors
Simply put, this is wrong because it unnecessarily opens up possibilities to MANY bugs. When the #Override is invoked, the state of the object may be inconsistent and/or incomplete.
A quote from Effective Java 2nd Edition, Item 17: Design and document for inheritance, or else prohibit it:
There are a few more restrictions that a class must obey to allow inheritance. Constructors must not invoke overridable methods, directly or indirectly. If you violate this rule, program failure will result. The superclass constructor runs before the subclass constructor, so the overriding method in the subclass will be invoked before the subclass constructor has run. If the overriding method depends on any initialization performed by the subclass constructor, the method will not behave as expected.
Here's an example to illustrate:
public class ConstructorCallsOverride {
public static void main(String[] args) {
abstract class Base {
Base() {
overrideMe();
}
abstract void overrideMe();
}
class Child extends Base {
final int x;
Child(int x) {
this.x = x;
}
#Override
void overrideMe() {
System.out.println(x);
}
}
new Child(42); // prints "0"
}
}
Here, when Base constructor calls overrideMe, Child has not finished initializing the final int x, and the method gets the wrong value. This will almost certainly lead to bugs and errors.
Related questions
Calling an Overridden Method from a Parent-Class Constructor
State of Derived class object when Base class constructor calls overridden method in Java
Using abstract init() function in abstract class’s constructor
See also
FindBugs - Uninitialized read of field method called from constructor of superclass
On object construction with many parameters
Constructors with many parameters can lead to poor readability, and better alternatives exist.
Here's a quote from Effective Java 2nd Edition, Item 2: Consider a builder pattern when faced with many constructor parameters:
Traditionally, programmers have used the telescoping constructor pattern, in which you provide a constructor with only the required parameters, another with a single optional parameters, a third with two optional parameters, and so on...
The telescoping constructor pattern is essentially something like this:
public class Telescope {
final String name;
final int levels;
final boolean isAdjustable;
public Telescope(String name) {
this(name, 5);
}
public Telescope(String name, int levels) {
this(name, levels, false);
}
public Telescope(String name, int levels, boolean isAdjustable) {
this.name = name;
this.levels = levels;
this.isAdjustable = isAdjustable;
}
}
And now you can do any of the following:
new Telescope("X/1999");
new Telescope("X/1999", 13);
new Telescope("X/1999", 13, true);
You can't, however, currently set only the name and isAdjustable, and leaving levels at default. You can provide more constructor overloads, but obviously the number would explode as the number of parameters grow, and you may even have multiple boolean and int arguments, which would really make a mess out of things.
As you can see, this isn't a pleasant pattern to write, and even less pleasant to use (What does "true" mean here? What's 13?).
Bloch recommends using a builder pattern, which would allow you to write something like this instead:
Telescope telly = new Telescope.Builder("X/1999").setAdjustable(true).build();
Note that now the parameters are named, and you can set them in any order you want, and you can skip the ones that you want to keep at default values. This is certainly much better than telescoping constructors, especially when there's a huge number of parameters that belong to many of the same types.
See also
Wikipedia/Builder pattern
Effective Java 2nd Edition, Item 2: Consider a builder pattern when faced with many constructor parameters (excerpt online)
Related questions
When would you use the Builder Pattern?
Is this a well known design pattern? What is its name?
Here's an example which helps to understand this:
public class Main {
static abstract class A {
abstract void foo();
A() {
System.out.println("Constructing A");
foo();
}
}
static class C extends A {
C() {
System.out.println("Constructing C");
}
void foo() {
System.out.println("Using C");
}
}
public static void main(String[] args) {
C c = new C();
}
}
If you run this code, you get the following output:
Constructing A
Using C
Constructing C
You see? foo() makes use of C before C's constructor has been run. If foo() requires C to have a defined state (i.e. the constructor has finished), then it will encounter an undefined state in C and things might break. And since you can't know in A what the overwritten foo() expects, you get a warning.
Invoking an overridable method in the constructor allows subclasses to subvert the code, so you can't guarantee that it works anymore. That's why you get a warning.
In your example, what happens if a subclass overrides getTitle() and returns null ?
To "fix" this, you can use a factory method instead of a constructor, it's a common pattern of objects instanciation.
Here is an example that reveals the logical problems that can occur when calling an overridable method in the super constructor.
class A {
protected int minWeeklySalary;
protected int maxWeeklySalary;
protected static final int MIN = 1000;
protected static final int MAX = 2000;
public A() {
setSalaryRange();
}
protected void setSalaryRange() {
throw new RuntimeException("not implemented");
}
public void pr() {
System.out.println("minWeeklySalary: " + minWeeklySalary);
System.out.println("maxWeeklySalary: " + maxWeeklySalary);
}
}
class B extends A {
private int factor = 1;
public B(int _factor) {
this.factor = _factor;
}
#Override
protected void setSalaryRange() {
this.minWeeklySalary = MIN * this.factor;
this.maxWeeklySalary = MAX * this.factor;
}
}
public static void main(String[] args) {
B b = new B(2);
b.pr();
}
The result would actually be:
minWeeklySalary: 0
maxWeeklySalary: 0
This is because the constructor of class B first calls the constructor of class A, where the overridable method inside B gets executed. But inside the method we are using the instance variable factor which has not yet been initialized (because the constructor of A has not yet finished), thus factor is 0 and not 1 and definitely not 2 (the thing that the programmer might think it will be). Imagine how hard would be to track an error if the calculation logic was ten times more twisted.
I hope that would help someone.
If you call methods in your constructor that subclasses override, it means you are less likely to be referencing variables that don’t exist yet if you divide your initialization logically between the constructor and the method.
Have a look on this sample link http://www.javapractices.com/topic/TopicAction.do?Id=215
I certainly agree that there are cases where it is better not to call some methods from a constructor.
Making them private takes away all doubt: "You shall not pass".
However, what if you DO want to keep things open.
It's not just the access modifier that is the real problem, as I tried to explain here. To be completely honest, private is a clear showstopper where protected usually will still allow a (harmful) workaround.
A more general advice:
don't start threads from your constructor
don't read files from your constructor
don't call APIs or services from your constructor
don't load data from a database from your constructor
don't parse json or xml documents from your constructor
Don't do so (in)directly from your constructor. That includes doing any of these actions from a private/protected function which is called by the constructor.
Calling an start() method from your constructor could certainly be a red flag.
Instead, you should provide a public init(), start() or connect() method. And leave the responsibility to the consumer.
Simply put, you want to separate the moment of "preparation" from the "ignition".
if a constructor can be extended then it shouldn't self-ignite.
If it self-ignites then it risks being launched before being fully constructed.
After all, some day more preparation could be added in the constructor of a subclass. And you don't have any control over the order of execution of the constructor of a super class.
PS: consider implementing the Closeable interface along with it.
In the specific case of Wicket: This is the very reason why I asked the Wicket
devs to add support for an explicit two phase component initialization process in the framework's lifecycle of constructing a component i.e.
Construction - via constructor
Initialization - via onInitilize (after construction when virtual methods work!)
There was quite an active debate about whether it was necessary or not (it fully is necessary IMHO) as this link demonstrates http://apache-wicket.1842946.n4.nabble.com/VOTE-WICKET-3218-Component-onInitialize-is-broken-for-Pages-td3341090i20.html)
The good news is that the excellent devs at Wicket did end up introducing two phase initialization (to make the most aweseome Java UI framework even more awesome!) so with Wicket you can do all your post construction initialization in the onInitialize method that is called by the framework automatically if you override it - at this point in the lifecycle of your component its constructor has completed its work so virtual methods work as expected.
I guess for Wicket it's better to call add method in the onInitialize() (see components lifecycle) :
public abstract class BasicPage extends WebPage {
public BasicPage() {
}
#Override
public void onInitialize() {
add(new Label("title", getTitle()));
}
protected abstract String getTitle();
}