0

我是 AS3 的新手,我来自 Java 背景。在 AS3 中,我有一个已初始化的静态 const 对象 PRESETS,并尝试在构造函数中访问它,但我收到一个错误消息,指出该常量为空。在初始化常量之前是否调用了类构造函数?我希望常量在调用构造函数之前就可以使用了。谁能解释这里发生了什么?我想尝试完成这项工作。

我的代码如下:

public class TteColor {
    // This is the constant I'm trying to access from the constructor.
    public static const PRESETS:Object = {
      "WHITE":    new TteColor("#FFFFFF"),
      "BLACK":    new TteColor("#000000"),
      "GRAY":     new TteColor("#808080"),
      "RED":      new TteColor("#FF0000"),
      "GREEN":    new TteColor("#00FF00"),
      "BLUE":     new TteColor("#0000FF"),
      "YELLOW":   new TteColor("#FFFF00"),
      "CYAN":     new TteColor("#00FFFF"),
      "MAGENTA":  new TteColor("#FF00FF")
    };

    public static const COLOR_REGEX:RegExp = /^#[\dA-Fa-f]{6}$/;

    public var intValue:int;
    public var strValue:String;

    public function TteColor(color:String, defaultColor:TteColor = null) {
      trace("trace0");
      if (color != null && color.search(COLOR_REGEX) >= 0) {
        trace("trace1");
        strValue = color.toUpperCase();
        intValue = uint("0x" + strValue.substring(1));
      } else {
        trace("trace2");
        if (!defaultColor) {
          trace("trace2.1");
          trace("PRESETS: " + PRESETS);
          defaultColor = PRESETS["WHITE"]; // PRESETS constant is still null here?
        }
        trace("trace3");
        strValue = defaultColor.strValue;
        intValue = defaultColor.intValue;
        Logger.warning("Incorrect color value. Defaulting to: " + strValue);
      }
    }
}

输出:

输出显示 PRESETS 常量为空。

trace0
trace2
trace2.1
PRESETS: null
TypeError: Error #1009: Cannot access a property or method of a null object reference.

更改为静态变量

我将 PRESETS 常量更改为静态变量并静态初始化值。这可以正常工作。当静态变量起作用时,为什么常量会失败?

// Statically initialize PRESETS
{
  PRESETS = new Object();
  PRESETS["WHITE"] = new TteColor("#FFFFFF");
  PRESETS["BLACK"] = new TteColor("#000000");                                                                                                                                                                                                   PRESETS["GRAY"] = new TteColor("#808080");
  PRESETS["RED"] = new TteColor("#FF0000");
  PRESETS["GREEN"] = new TteColor("#00FF00");
  PRESETS["BLUE"] = new TteColor("#0000FF");
  PRESETS["YELLOW"] = new TteColor("#FFFF00");
  PRESETS["CYAN"] = new TteColor("#00FFFF");                                                                                                                                                                                                    PRESETS["MAGENTA"] = new TteColor("#FF00FF");
}

// Changed from constant to static class variable. This works fine.
public static var PRESETS:Object;
4

3 回答 3

4

在初始化常量之前是否调用了类构造函数?

通常没有。

但是您正在从静态成员中显式调用您的类构造函数:

"WHITE":    new TteColor("#FFFFFF"),
"BLACK":    new TteColor("#000000"),
// etc...

因此,当该静态对象试图创建自己时,它必须运行类构造函数。在您的类构造函数中,您引用了尚未完成自身创建的静态对象。

您的第二个示例有效,因为您在开始调用类构造函数之前完成了对象的构造。(此时对象仍然是空的,但至少它不是空的)。

于 2013-09-21T20:34:49.287 回答
3

静态成员是类本身的成员,而不是实例上的成员。因此,对静态成员的调用永远不会调用构造函数,因为您不是从类创建实例/对象,而是在调用类本身的函数/成员。

于 2013-09-21T11:32:54.850 回答
1

使用 satic 常量时,您正在尝试创建同一类的对象。因此,在进行静态 const 初始化时,它失败了。

于 2013-09-22T11:40:42.510 回答