Any way to _not_ call superclass constructor in Ja

2019-02-05 16:50发布

If I have a class:

class A {
   public A() { }
}

and another

class B extends A {
   public B() { }
}

is there any way to get B.B() not to call A.A()?

13条回答
Anthone
2楼-- · 2019-02-05 17:01

Every superclass needs to be constructed and there is no other way then calling a constructor.

查看更多
ら.Afraid
3楼-- · 2019-02-05 17:02

Every object in java is a subclass of Object (object with a capital 'O'). when you create an object of a subclass the super class constructor is invoked. Even if your class is not inhereting anyother class, implicitly it is inheriting Object, so the Object constructor has to be called. So super() is invoked for this purpose.

查看更多
唯我独甜
4楼-- · 2019-02-05 17:04

The possibility is that you can call the super class constructor of your choice. That is possible by calling the super class constructor explicitly as :

super(para_1, para_2,........);

class BaseA {
    BaseA(){
        System.out.println("This is BaseA");
    }
    BaseA(int a){
        System.out.println("This is BaseA a");
    }


}

class A extends BaseA {

    A(){
        super(5);
        System.out.println("This is A");
    }

    public static void main(String[] args) {
        A obj=new A();

    }
}


Output will be:
This is BaseA a
This is A
查看更多
男人必须洒脱
5楼-- · 2019-02-05 17:05
  1. As pointed out by another poster, B doesn't extend A, so it won't call A's constructor anyways.

  2. There is no way to do this in Java.

  3. You can probably accomplish equivalently what you want to do as follows:

a) in each class of your hierarchy, include a constructor with a unique signature that calls the superclass's constructor with its arguments. For example, declare a class "Noop" and a constructor that takes that as an argument:

public class NoOp {
}

public class class1 {
    class1() {
        System.out.println("class1() called");
    }
    class1(String x, String y) {
        System.out.println("class1(String, String) called");
}
    class1(NoOp x) {
        System.out.println("class1(NoOp) called");
    }
}

public class class2 extends class1 {
    class2() {
        System.out.println("class2() called");
    }
    class2(String x, String y) {
        System.out.println("class2(String, String) called");
}
    class2(NoOp x) {
        super(x);
        System.out.println("class2(NoOp) called");
    }
}

public class class3 extends class2 {
    class3() {
        System.out.println("class3() called");
    }
    class3(String x, String y) {
        super(new NoOp());
        System.out.println("class3(String, String) called");
    }
    class3(NoOp x) {
        super(x);
        System.out.println("class3(NoOp) called");
    }
    public static void main(String args[]) {
        class3 x = new class3("hello", "world");
    }
}

If you run this you will get the output

class1(NoOp) called
class2(NoOp) called
class3(String, String) called

So, effectively you have created a class3 constructor that only calls constructors that don't do anything.

查看更多
对你真心纯属浪费
6楼-- · 2019-02-05 17:06

Java deserialisation doesn't call the constructor, but it seems that it is based on some internal JVM tricks.

However, there is a framework that allows you to do that in a portable manner: Objenesis (http://www.theserverside.com/discussions/thread/44297.html)

I've seen this recently in Spring, when using CGLIB proxies, Spring creates two class instances, but the constructor is called only once: https://stackoverflow.com/a/11583641/2557118

This behavior is added in Spring 4:

CGLIB-based proxy classes no longer require a default constructor. Support is provided via the objenesis library which is repackaged inline and distributed as part of the Spring Framework. With this strategy, no constructor at all is being invoked for proxy instances anymore.

查看更多
做个烂人
7楼-- · 2019-02-05 17:08

Assuming you mean

class B extends A {
     public B() { }
}

then sure you can

class B extends A {
     public B() {
         this(abort());
     }
     private B(Void dummy) {
         /* super(); */
     }
     private static Void abort() {
         throw null;
     }
}

Not very useful. The interface [not Java keyword] to class A says that you need to run its constructor in order to construct it, not unreasonably. The exception is that serialisable classes are constructed without calling the constructors of the serialisable classes.

查看更多
登录 后发表回答