【问题标题】:Always execute some code after overloaded constructors在重载构造函数后总是执行一些代码
【发布时间】:2023-03-30 19:16:01
【问题描述】:

我希望在这个子类的每个重载构造函数中执行一些代码(例如,“setBackground(Color.BLACK);”)(或者我也可以表示“一些代码”必须在这个子类的实例之后执行创建)。但是这个“一些代码”只能在我们的子类中使用/调用,而且只能使用一次。并且这个子类的每一个重载的构造函数必须总是调用超类的适当的重载构造函数。

public class JLProgressBar extends JProgressBar{

    public JLProgressBar(){

        super();

    }

    public JLProgressBar(int orient){

        super(orient);

    }

    public JLProgressBar(int min, int max){

        super(min,max);

    }

    public JLProgressBar(int orient, int min, int max){

        super(orient,min,max);

    }

    public JLProgressBar(BoundedRangeModel newModel){

        super(newModel);

    }

}

【问题讨论】:

  • initialiser block 能满足您的需求吗?
  • @BeUndead,是的,非常感谢!但不好的是,它在构造函数之前执行。
  • 它们在构造函数中调用super 之后运行。因此,在您发布的上下文中,它应该有效地所有这些之后。这些构造函数中是否还有其他未在此处发布的代码运行?
  • @BeUndead,重新检查一下 - 你是对的!一切正常。谢谢!

标签: java object constructor instance


【解决方案1】:

您可以使用实例初始化程序。此初始化程序可以处理所有构造函数变体所需的“一些代码”。

public class JLProgressBar extends JProgressBar{

    public JLProgressBar(){
        super();
    }

    public JLProgressBar(int orient){
        super(orient);
    }

    public JLProgressBar(int min, int max){
        super(min,max);
    }

    public JLProgressBar(int orient, int min, int max){
        super(orient,min,max);
    }

    public JLProgressBar(BoundedRangeModel newModel){
        super(newModel);
    }

    // instance initializer (called for every constructor
    {
        // "some code"
    }
}

注意:此实例初始化程序将在 超级构造函数之后但 构造函数中的任何其他代码之前运行。所以

public class Bar
{
    protected int a;

    public Bar()
    {
        a = 2;
        System.out.println(a);
    }

    {
        a = 1;
        System.out.println(a);
    }
}

public class Foo extends Bar
{
    public Foo()
    {
        super();
        a = 4;
        System.out.println(a);
    }

    {
        a = 3;
        System.out.println(a);
    }
}

public static void main(String[] args)
{
    new Foo();
}

...将打印

1
2
3
4

【讨论】:

  • init() 多次使用(但必须只使用一次)。无论如何,谢谢!
  • 我不明白你的评论。 init() 只能在每个构造函数中使用一次。
  • @marick 只有一个构造函数将被调用,因此该方法只会被调用一次(每个实例)((尽管 IMO 实例初始化器更合适))跨度>
  • @ultimate 您在代码中使用了几次 init()(您在每个重载的构造函数中都使用了它)。我希望它只使用一次。
  • @user85421:感谢您的提示。不知道实例初始化器 - 只知道静态初始化器。分别更新我的答案
【解决方案2】:

将评论转换为答案以供将来参考。

Java 的Initialiser blocks 应该可以解决这个问题。这些在调用super 之后直接注入到每个构造函数中,这(在您提供的示例中)应该涵盖在适当时间发生的情况。此外,这些只会运行一次,并且保证会为每个创建的实例运行(无论是否有人子类化了您的类等)。

例如

public class YourJProgressBar extends JProgressBar {

    public YourJProgressBar() {
        super();
    }

    {
        // Whatever code you want in here, will run immediately after the call
        // to 'super' in any given constructor.  Note, in cases where the call
        // to 'super' is implicit, it will run after that implicit call
        // instead of just never running.
        this.setValue(10);
    }
}

【讨论】:

    【解决方案3】:

    试试这个。每次加载类时都会调用static 块。

    
    public class JLProgressBar extends JProgressBar{
    
        static {
            System.out.println("hhh");
        }
    
        public JLProgressBar(){
            super();
        }
    
        public JLProgressBar(int orient){
            super(orient);
        }
    
        public JLProgressBar(int min, int max){
            super(min,max);
        }
    
        public JLProgressBar(int orient, int min, int max){
            super(orient,min,max);
        }
    
        public JLProgressBar(BoundedRangeModel newModel){
            super(newModel);
        }
    }
    

    【讨论】:

    • 我需要在创建类的实例后执行它(并且它必须不在静态上下文中)。
    • @marick0073 如果你想在构造函数中调用它,创建一个函数并从每个重载的构造函数中调用它
    • 正如我提到的,它只能被调用/使用一次(所以我不能从每个重载的构造函数中调用它)。
    • 只有一个构造函数会被调用,所以方法只会被调用一次(每个实例)
    • @user85421 是的,我明白这一点。但是函数在少数地方使用(在每个重载的构造函数中)。我希望它只在一个地方使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-27
    • 2011-11-21
    • 2017-01-10
    • 2016-05-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多