Java AWT:Font是一个轻量级对象吗?

Ton*_*ony 10 java performance fonts awt

Font使用Java的AWT时创建对象有多贵?我应该Font在实际时缓存,还是仅仅是对重量级字体的轻量级引用,AWT已在内部缓存?

Rev*_*nzo 7

如果你看一下Font的源代码(这是OpenJDK),那么名称,样式,大小的构造函数显然是轻量级的:

public Font(String name, int style, int size) {
    this.name = (name != null) ? name : "Default";
    this.style = (style & ~0x03) == 0 ? style : 0;
    this.size = size;
    this.pointSize = size;
}
Run Code Online (Sandbox Code Playgroud)

但是,获取文件和fontformat的构造函数是:

private Font(File fontFile, int fontFormat,
             boolean isCopy, CreatedFontTracker tracker)
    throws FontFormatException {
    this.createdFont = true;
    /* Font2D instances created by this method track their font file
     * so that when the Font2D is GC'd it can also remove the file.
     */
    this.font2DHandle =
        FontManager.createFont2D(fontFile, fontFormat,
                                 isCopy, tracker).handle;
    this.name = this.font2DHandle.font2D.getFontName(Locale.getDefault());
    this.style = Font.PLAIN;
    this.size = 1;
    this.pointSize = 1f;
}
Run Code Online (Sandbox Code Playgroud)

这显然是重量级的(特别是FontManager.createFont2D(...)部分.这个构造函数只由Font.createFont()使用.

总的来说,如果你使用系统中的字体,你就可以了,只需创建它并按名称引用它.如果您提供自己的字体(即:来自TrueType文件),您可能最好缓存它.(也就是说,IIRC,有一种方法可以简单地将文件加载到AWT的缓存中,这样你就可以简单地通过名称来引用它.)

进一步深入到源代码,所有函数,如getFamily(),getFontName(),getNumGlyphs(),首先调用getFont2D(),这本质上是:

private Font2D getFont2D() {
    // snip
    if (font2DHandle == null) {
        font2DHandle =
            FontManager.findFont2D(name, style,
                                   FontManager.LOGICAL_FALLBACK).handle;
    }
    /* Do not cache the de-referenced font2D. It must be explicitly
     * de-referenced to pick up a valid font in the event that the
     * original one is marked invalid
     */
    return font2DHandle.font2D;
}
Run Code Online (Sandbox Code Playgroud)

所以,这表明每个字体都是轻量级的,它从负责缓存字体的FontManager中提取必要的信息.