相关疑难解决方法(0)

构造函数中的可覆盖方法调用有什么问题?

我有一个Wicket页面类,它根据抽象方法的结果设置页面标题.

public abstract class BasicPage extends WebPage {

    public BasicPage() {
        add(new Label("title", getTitle()));
    }

    protected abstract String getTitle();

}
Run Code Online (Sandbox Code Playgroud)

NetBeans通过消息"构造函数中的可覆盖方法调用"警告我,但它应该有什么问题呢?我能想象的唯一选择是将其他抽象方法的结果传递给子类中的超级构造函数.但是很多参数很难读懂.

java oop inheritance constructor overriding

366
推荐指数
4
解决办法
12万
查看次数

`this`如何通过发布内部类实例引用外部类转义?

之前的问题略有不同,但要求是/否答案,但我正在寻找书中遗漏的解释(Java Concurrency in Practice),这个明显的大错误将如何被恶意或意外地利用.

可以发布对象或其内部状态的最终机制是发布内部类实例,如清单3.7中的ThisEscape所示.当ThisEscape发布EventListener时,它也隐式发布封闭的ThisEscape实例,因为内部类实例包含对封闭实例的隐藏引用.

清单3.7.隐式允许此引用转义.不要这样做.

public class ThisEscape {
    public ThisEscape(EventSource source) {
        source.registerListener(
            new EventListener() {
                public void onEvent(Event e) {
                    doSomething(e);
                }
            });
    }
}
Run Code Online (Sandbox Code Playgroud)

3.2.1.安全施工实践

ThisEscape说明了一个重要的特殊情况 - 当它在构造过程中引用逃逸时.发布内部EventListener实例时,封闭的ThisEscape实例也是如此.但是只有在构造函数返回后,对象才处于可预测的一致状态,因此从构造函数中发布对象可以发布未完全构造的对象.即使发布是构造函数中的最后一个语句,也是如此.如果此参考在施工期间逃逸,则认为该物体构造不正确.[8]

[8]更具体地说,在构造函数返回之前,此引用不应从线程中转义.这个引用可以由构造函数存储在某处,只要它在构造之后不被另一个线程使用.清单3.8中的SafeListener使用了这种技术.

在施工期间不要让此参考物逃逸.

在完成构建之前,有人会如何编写代码以进入OuterClass?hidden inner class reference第一段用斜体字提到的是什么?

java concurrency multithreading constructor

30
推荐指数
3
解决办法
2843
查看次数

当Base类构造函数在Java中调用重写方法时,Derived类对象的状态

请参考下面的Java代码:

class Base{
     Base(){
         System.out.println("Base Constructor");
         method();
     }
     void method(){}    
}

class Derived extends Base{
    int var = 2;
    Derived(){
         System.out.println("Derived Constructor");  
    }

     @Override
     void method(){
        System.out.println("var = "+var);
     }
 }

class Test2{
    public static void main(String[] args) {
        Derived b = new Derived();
    }
}
Run Code Online (Sandbox Code Playgroud)

看到的输出是:

Base Constructor
var = 0
Derived Constructor
Run Code Online (Sandbox Code Playgroud)

我认为var = 0的发生是因为Derived对象是半初始化的; 类似于Jon Skeet在这里所说的

我的问题是:

如果尚未创建Derived类对象,为什么会调用重写的方法?

在什么时间点,var赋值为0?

是否存在需要此类行为的用例?

java inheritance constructor

12
推荐指数
2
解决办法
4097
查看次数

在抽象类的构造函数中使用抽象的init()函数

我有这样的事情:

    public abstract class Menu {
     public Menu() {
      init();
     }

     protected abstract void init();

     protected void addMenuItem(MenuItem menuItem) {
      // some code...
     }
    }

    public class ConcreteMenu extends Menu {
     protected void init() {
      addMenuItem(new MenuItem("ITEM1"));
      addMenuItem(new MenuItem("ITEM2"));
      // ....
     }
    }

//Somewhere in code
Menu menu1 = new ConcreteMenu();
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,超类的init方法是抽象的,并且在创建对象后由构造函数自动调用.

我很好奇我是否可以遇到像这样的代码的某些问题,当我需要创建一些这样的结构时,其结构不会及时更改.

会有更好的方法吗?它适用于Java,但它可以在C++和ActionScript中使用吗?

谢谢你的答案.

java

10
推荐指数
1
解决办法
5202
查看次数