当我使用 Java 的 AWT 时,创建一个 Font 对象的开销有多大?我应该在可行的时候缓存 Font,还是它只是对 AWT 已经在内部缓存的重量级字体的轻量级引用?
最佳答案
如果你查看 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;
}
但是,采用文件和字体格式的构造函数是:
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;
}
这显然是重量级的(特别是 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;
}
所以,这表明每种字体都是轻量级的,它从负责缓存字体的 FontManager 中提取必要的信息。
关于Java AWT : Is Font a lightweight object?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6102602/