I want to wrap a class in Java but the problem is as follows:
public class A {
public A() {
doSomething();
}
public void doSomething() {
}
}
Now when I try to wrap this class and delegate all methods to the wrapper
public class Wrapper extends A {
private final A a;
public Wrapper(A a) {
super();
this.a = a;
}
#Override
public void doSomething() {
this.a.doSomeThing();
}
}
of course I get a NPE as 'a' is still null as it is set after the super()-call which calls the overriden doSomething() method. Is there any solution for this problem? The only thing that came to my mind was making a factory method and setting a static variable holding the reference to a but this seems ugly to me.
I'd recommend changing the code so that doSomething is not called in the constructor.
Alternatively split A into an interface and implementation Wrapper implements the interface and does not inherit from A
public interface IA {
public void doSomething() {
}
}
public class A implements IA {
public A() {
doSomething();
}
public void doSomething() {
}
}
public class Wrapper implements IA {
private final IA a;
public Wrapper(IA a) {
this.a = a;
doSomething();
}
#Override
public void doSomething() {
a.doSomeThing();
}
}
Change your Wrapper this way. You do not need to hold A explicitly. The expression super is the same as your filed:
class Wrapper extends A {
public Wrapper() {
}
#Override public void doSomething() {
super.doSomething();
}
}
Or otherwise extract an interface and change your code like this:
class Wrapper implements AA {
private final AA child;
public Wrapper(AA child) {
this.child = child;
}
#Override public void doSomething() {
child.doSomething();
}
}
class A implements AA {
public A() {
doSomething();
}
#Override public void doSomething() {}
}
interface AA {
public void doSomething();
}
A way for this to be avoided is by exposing an init method (or any other name) from your base class (if you are in control of its logic). Then move the call from the constructor to the init method:
public class A {
public A() {
}
public void init() {
doSomething();
}
public void doSomething() {
}
}
You should update your code to call the init method after making an instance of the class, which may be a bit of boilerplate:
A instance = new Wrapper();
instance.init();
instead of just
A instance = new Wrapper();
If you use Spring and DI, you can specify an init-method in the xml context, so Spring will call it for you when it resolves the dependency.
In case the doSomething method is public, and accepts no arguments, you can use it directly instead of the init method both in code and with Spring.
In general, use of overridable methods in a constructor is an anti-pattern, due to the problem you have encountered. There is no way to predict how a derived class will override the methods and if they rely on non-initialized resources, then you are in trouble.
two small changes, young one you need
public class Wrapper extends A {
private final A a;
public Wrapper(A a) {
super();
this.a = a;
//this will execute method doSomething wrom Wrapper class after variable a is set
doSomething();
}
#Override
public void doSomething() {
//this will prevent to call metod from superclass constructor, bit risky thou
if (a!=null)
this.a.doSomething();
}
}
but overriding methods which are called in constructo is generally bad practice and smells terrible
Related
I'm trying to build a base class with a method that needs to call a private method before and after performing the actual logic.
public abstract class Base {
public Base() {}
private void before() {
// doSomething
}
private void after() {
// doSomething
}
public void actual(Object object) {
before();
// doSomething
after();
}
}
public class SomeClass extends Base {
public SomeClass() {}
public void actual(Object object) {
// actual code that needs to be executed between before and after methods.
}
}
How would I go about this?
Create another method that can be overridden and implemented instead of overriding actual directly.
E.g.
public void actual(Object object) {
before();
doActual(object);
after();
}
protected abstract void doActual(Object object);
You could make the actual() method final if you want to ensure that nobody overrides it by mistake.
You can make the method as abstract e.g.
protected abstract void actual(Object object);
and create another public method which is going to be called
public void init(Object object){
before();
actual(object);
after();
}
I have a class A that extends a class B.
A is defined like this, it also overrides a method of B:
class A extends B
{
public A() {
super();
}
#Override
public void doSomething(){
//does something
}
}
B is defined like this:
public class B
{
public B(){
doSomething();
}
public void doSomething(){
//does something
}
}
So if I initialize an object of A, the constructor calls the one of the superclass that calls the method doSomething(). But which one will be executed? B's implementation or the overriden one in A?
That is a common bug, only call final methods in constructor, the method from A will be called.
Btw Sonar(if you have it) will trigger a rule here saying that you should not call polymorphic methods inside a constructor.
If the class Overrides a method, then the overriden method will be called. Try the example below:
public class A {
void doSomething() {
System.out.println("a");
}
}
public class B extends A {
#Override
void doSomething() {
System.out.println("b");
}
}
A a = new B();
a.doSomething(); // will print "b"
Java 8 introduces default methods to provide the ability to extend interfaces without the need to modify existing implementations.
I wonder if it's possible to explicitly invoke the default implementation of a method when that method has been overridden or is not available because of conflicting default implementations in different interfaces.
interface A {
default void foo() {
System.out.println("A.foo");
}
}
class B implements A {
#Override
public void foo() {
System.out.println("B.foo");
}
public void afoo() {
// how to invoke A.foo() here?
}
}
Considering the code above, how would you call A.foo() from a method of class B?
As per this article you access default method in interface A using
A.super.foo();
This could be used as follows (assuming interfaces A and C both have default methods foo())
public class ChildClass implements A, C {
#Override
public void foo() {
//you could completely override the default implementations
doSomethingElse();
//or manage conflicts between the same method foo() in both A and C
A.super.foo();
}
public void bah() {
A.super.foo(); //original foo() from A accessed
C.super.foo(); //original foo() from C accessed
}
}
A and C can both have .foo() methods and the specific default implementation can be chosen or you can use one (or both) as part of your new foo() method. You can also use the same syntax to access the default versions in other methods in your implementing class.
Formal description of the method invocation syntax can be found in the chapter 15 of the JLS.
This answer is written mainly for users who are coming from question 45047550 which is closed.
Java 8 interfaces introduce some aspects of multiple inheritance. Default methods have an implemented function body. To call a method from the super class you can use the keyword super, but if you want to make this with a super interface it's required to name it explicitly.
class ParentClass {
public void hello() {
System.out.println("Hello ParentClass!");
}
}
interface InterfaceFoo {
public default void hello() {
System.out.println("Hello InterfaceFoo!");
}
}
interface InterfaceBar {
public default void hello() {
System.out.println("Hello InterfaceBar!");
}
}
public class Example extends ParentClass implements InterfaceFoo, InterfaceBar {
public void hello() {
super.hello(); // (note: ParentClass.super could not be used)
InterfaceFoo.super.hello();
InterfaceBar.super.hello();
}
public static void main(String[] args) {
new Example().hello();
}
}
Output:
Hello ParentClass!
Hello InterfaceFoo!
Hello InterfaceBar!
The code below should work.
public class B implements A {
#Override
public void foo() {
System.out.println("B.foo");
}
void aFoo() {
A.super.foo();
}
public static void main(String[] args) {
B b = new B();
b.foo();
b.aFoo();
}
}
interface A {
default void foo() {
System.out.println("A.foo");
}
}
Output:
B.foo
A.foo
You don't need to override the default method of an interface. Just call it like the following:
public class B implements A {
#Override
public void foo() {
System.out.println("B.foo");
}
public void afoo() {
A.super.foo();
}
public static void main(String[] args) {
B b=new B();
b.afoo();
}
}
Output:
A.foo
It depends on your choice whether you want to override the default method of an interface or not. Because default are similar to instance method of a class which can be directly called upon the implementing class object. (In short default method of an interface is inherited by implementing class)
Consider the following example:
interface I{
default void print(){
System.out.println("Interface");
}
}
abstract class Abs{
public void print(){
System.out.println("Abstract");
}
}
public class Test extends Abs implements I{
public static void main(String[] args) throws ExecutionException, InterruptedException
{
Test t = new Test();
t.print();// calls Abstract's print method and How to call interface's defaut method?
}
}
I'm very new to the java 8 features and try to understand default methods. Is there an easier way to invoke a default method by another default method of the same interface than using an anonymous class?
For example:
public class Frame{
public static void main(String... args){
Frame.C c= new Frame.C();
c.doSomething();
}
public interface A{
public default void doSomething(){
System.out.println("A");
}
}
public interface B extends A {
#Override
public default void doSomething(){
System.out.println("B");
//is there an easier way to invoke that method??
new B(){}.other();
}
default public void other(){
//doSomething();
System.out.println("other");
}
}
public static class C implements B{
#Override
public void other(){
Lambda.B.super.other();
System.out.println("C");
}
}
}
Your intention is not entirely clear, but the construct new B(){}.other(); implies two things:
You don’t want to invoke an overriding method implementation
The instance on which you invoke other() is obviously irrelevant when invoking it on an entirely different instance (new B(){}) is a viable solution
These two things together imply that you should use a static method instead:
public interface B extends A {
#Override
public default void doSomething(){
System.out.println("B");
otherInB();
}
default public void other(){
otherInB();
}
static void otherInB() {
//doSomething();
System.out.println("other");
}
}
Since your original method names did not carry useful information, it’s not possible to suggest a useful name for that static method either.
Note that Java 9 is going to introduce support for private methods in interfaces which allows hiding otherInB() to other classes and even making it non-static in case it has to use other methods on the same instance.
If the visibility of the method in Java 8 is an issue, consider that the actual place of a non-polymorphic method is irrelevant, so you can always use a companion class:
public interface B extends A {
#Override
public default void doSomething(){
System.out.println("B");
BHelper.other();
}
default public void other(){
BHelper.other();
}
}
…
/* not public */ class BHelper {
/* not public */ static void other() {
//doSomething();
System.out.println("other");
}
}
This even works if the implementation needs the actual B instance as you may pass it as a parameter.
public interface B extends A {
#Override
public default void doSomething(){
System.out.println("B");
BHelper.other(this);
}
default public void other(){
BHelper.other(this);
}
}
…
/* not public */ class BHelper {
/* not public */ static void other(B instance) {
//doSomething();
System.out.println("other");
}
}
What is the difference between these two calls? How should this be done properly?
//package test;
public class SomeClass {
public SomeClass() {
doSomething();//Warning - Overridable method call in constructor
SomeClass.this.doSomething();//Seems OK
}
public void doSomething() {
//...
}
}
I want to use doSomething() just for convenience in the same class. I have no intentions to override it later. One idea is to declare it final. But still it is not clear if SomeClass.this.doSomething(); is safe to use in this situation.
The compiler warning notification somewhat says what can happen. If a subclass overrides the doSomething method, it can change the behavior when creating the class instance, which may be dangerous or not, depending on your design. Note that it's a warning, not a compiler exception.
To prove this, just extended your code to test it:
class SomeClass {
public SomeClass() {
doSomething();//Warning - Overridable method call in constructor
SomeClass.this.doSomething();//Seems OK, but is not
}
public void doSomething() {
System.out.println("parent");
}
}
public class SomeOtherClass extends SomeClass {
#Override
public void doSomething() {
System.out.println("child");
}
public static void main(String[] args) {
SomeClass a = new SomeClass();
SomeOtherClass b = new SomeOtherClass();
}
}
Prints:
parent
parent
child
child
If you just want that no other class can override doSomething method, mark it as final:
class SomeClass {
public SomeClass() {
doSomething();//Warning - Overridable method call in constructor
SomeClass.this.doSomething();//Seems OK
}
public final void doSomething() {
System.out.println("parent");
}
}
Then if any subclass tries to override it, the compiler will throw an error:
public class SomeOtherClass extends SomeClass {
#Override
public void doSomething() { //compiler error
System.out.println("child");
}
//...
}