繁体   English   中英

java中的static和final

[英]static and final in java

我正在从这个页面阅读Java中的枚举示例。

在第一个例子中,我唯一不理解的部分是在这部分代码中使用static关键字:

private static final List<Card> protoDeck = new ArrayList<Card>();

// Initialize prototype deck
static {
    for (Suit suit : Suit.values())
        for (Rank rank : Rank.values())
            protoDeck.add(new Card(rank, suit));
}

public static ArrayList<Card> newDeck() {
    return new ArrayList<Card>(protoDeck); // Return copy of prototype deck
}

为什么protoDeck声明为staticfinal 然后,使用静态循环初始化protoDeck。 我知道静态变量,它们在对象实例之间保留它们的值。 但这是一个单例类(私有构造函数),因此无法实例化。

那么这样做有什么好处呢? 如果proteDeck不是staticfinal会有什么影响?

从技术上讲,这不是一个单身人士类。 (单身有一个实例,这个没有 !)

它是ArrayList<Card>工厂方法newDeck方法的工作方式与构造函数对“CardArrayList”类的工作方式相同。 它不是Java构造函数,而是工厂方法,但除此之外它起到同样的作用:创建新的卡片组。

使用类CardArrayList和子类型ArrayList显然是一种替代方案。 试试这个练习:写一下类,这样就可以达到同样的目的。 尝试使用常量( static final )来保持初始对象集。 您会注意到这两者之间几乎没有什么区别,除了这种方法明确表示没有添加功能,但结果是“除了包含完整ArrayList<Card>ArrayList<Card> ”。 子类化可能意味着有额外的功能,例如确保甲板不被混淆。

static final变量包含用作新对象模板的原型。

代码的静态{....}部分将在Java虚拟机加载类的位置执行。

在您的代码段中,它用于初始化protoDeck ArrayList。

这不遵循Singleton模式,因为您的代码中没有证据表明该类只实例化了一次。

在类初始化( static括号中的代码)中,程序生protoDeck牌的所有卡并将其存储在protoDeck

调用newDeck ,将返回deck的浅表副本。 这意味着游戏中的所有牌对象都是同一个对象(只有一张“黑桃王牌”牌)。 不过,他们在几个不同的套牌中进行管理。

恕我直言,这是一个有点太复杂了这个例子中,它会更有意义,如果不是Cards ,而其他种类的类(即一个在那里他们代表的系统资源-database连接的初始化将是昂贵的/在RAM昂贵,或其他或类似 - )。

如果它不是静态的,代码将无法编译,因为newDeck方法是静态的,而newDeck是静态的,因为你没有为不同的卡获得不同的套牌。

让它不是最终的不会做任何不同的事情。 这是最终的,因为你不能分配不同的数组。 但你仍然可以添加它,所以它不是一成不变的。 所以这是一个常见的线索,但不是行为的改变。

Java中的final关键字可以实现各种编译时魔术。 例如,当编译器知道永远不会重新分配变量时,它可以执行“ memoization ”优化。

仅此一项是默认情况下final确定局部变量,参数和类成员的一个很好的理由 - 当然,除非你真的必须能够重新分配它们。

如果protoDeck不是static ,那么每张Card都会有一个,这不是一件好事。

显然,您只能使用static代码构造static变量。

final只是意味着protoDeck永远不会被替换(虽然它可以在内部更改)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM