java构造函数重载与this(),如何在此之前执行代码()

0 java constructor overloading

今天我在一个巨大的项目中遇到了一个有趣的情况 一个类有几个构造函数,它们用this()相互调用,最后会调用init(),build()等等.我想设置一个标志,然后调用this()和整个繁琐的过程,但调用this()它应该是第一个.

如何在不修改Contructor标头并设置标志的情况下修改此类中的代码?:)

我知道这听起来像是hackish,也许这不是在学校学到的,这就是为什么至少对我来说有趣.对于其他人来说在某些情况下也很有用.

这是一个基本的例子,我做了一些修改来模拟真正的问题,即init()方法. http://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html

public class Rectangle {
    private int x, y;
    private int width, height;
    private boolean flag;

    public Rectangle() {
      // execute code here, before this(), how?  -set the flag true for eg.
      this(0, 0, 0, 0);
    }
    public Rectangle(int width, int height) {
       // execute code here to, something different as above, before this(), how?   
       this(0, 0, width, height);
    }
    public Rectangle(int x, int y, int width, int height) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        init();
    }
    private void init(){
      if(flag){
      ... do something new, else or different as the original, maybe return, even exit too
      }

      ... do something... the old code
    }
}
Run Code Online (Sandbox Code Playgroud)

我有一个简单的实现,但在我写这个问题之前我也得到了第二个.

我的重要问题没有答案,但我希望这将是,我可以接受某人的答案,谁想要建立声誉.

init()方法不能被编码两次或者代码的逻辑写入2个位置,因为它不是一个好的编程范例,并且可能调用几百万行代码.

-------------编辑添加----------------

There is a way to known from which constructor was called: the full parametrized one or anything else with this() -I hope it gives more idea:

    public Rectangle(int x, int y, int width, int height) {
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;

            try {
                throw new RuntimeException("Hacking use a lot of imagination");
            } catch (Exception ex) {
                StackTraceElement[] stackTraces = ex.getStackTrace();
                // the first element is just above, no reason to check
                String thisClassName = getClass().getName();

                if (stackTraces[1].getClassName().equals(thisClassName)) {
                    if (stackTraces[1].getMethodName().equals("<init>")) {
                        flag = true;
                    }
                }
            }

            init();
        }

        private void init() {
            if (flag) {
                System.out.println("\"... do something new, else or different as the original, maybe return, even exit too\"");
            }

            System.out.println("\"... do something... the old code");

        }
Run Code Online (Sandbox Code Playgroud)

-----------------------编辑添加解决方案1 ​​ - 一个非常简单的案例

    public Rectangle() {
        // execute code here, before this(), how?  -set the flag true for eg.
        this(doVeryBanalHack(0, false), 0, 0, 0);
    }

    public Rectangle(int width, int height) {
        // execute code here to, something different as above, before this(), how?   
        this(doVeryBanalHack(0, false), 0, width, height);
    }

    public Rectangle(int x, int y, int width, int height) {
        this.x = doVeryBanalHack(x, true);
        this.y = y;
        this.width = width;
        this.height = height;
             // TODO deal with concurrency if you are in multithreaded environment, otherwise is done
           this.flag = nextValueOfFlag;
           init();
....}

   private static boolean nextValueOfFlag;

   private static int doVeryBanalHack(int retValue, boolean flagValue) {
           System.out.println("\"execute code here, before this() it is too simple, it is banal static function\");
         // TODO deal with concurrency if you are in multithreaded environment
        nextValueOfFlag = flagValue;
   }
Run Code Online (Sandbox Code Playgroud)

之所以在一个巨大的项目中无法改变功能签名是(其中之一)动态加载和反射用法: http://tutorials.jenkov.com/java-reflection/constructors.html http:// tutorials .jenkov.com/java的反射/动态类加载-reloading.html

http://www.java-forums.org/java-lang/7896-object-reflection-invoking-constructor-parameters.html 即使使用Class.forName("java.awt",某些IDE也足够智能地查找对此类的引用.Rectangle"),如果你有源,但如果他们在第三方库(插件),可能不是.许可证检查例程想隐藏自己,开发人员有点经验将"Rectangle"拆分为"Rect"+"tagle",甚至更复杂(decodeString)(但这已经足够了.非常怀疑你的超级智能编辑器可以找到参考比:)

下一个解决方案可以是反射(这是我在这里输入的第二个解决方案,我在上面写过) - 没人提到过

duf*_*ymo 5

总之一句:你做不到.Java之前禁止调用任何东西this,所以放弃了这个想法.

这可能会引发几百万行代码.

这本身就是一个问题.如果我是你,我会非常担心.

这听起来不像构造函数,更像是一个Builder模式.也许您应该考虑构造函数的替代方案.

你需要一个设置标志的构造函数,即使它是私有的.

public class Rectangle {
    private int x, y;
    private int width, height;
    private boolean flag;

    private Rectangle(int x, int y, int w, int h, boolean doInit) {
        this.x = y;
        this.y = y;
        this.width = w;
        this.height = h;
        this.flag = doInit;
        // Do what you must after this; adjust other ctors accordingly.
    }
}
Run Code Online (Sandbox Code Playgroud)

我也考虑重构其余部分.数百万行代码?天啊.