我来自Actionscript3背景,这是我第一次在我的生活中编写任何Java。 Hashtables似乎与Flash中的Dictionaries类似,但我想确保我正确使用它们。我相信Hashtable的类型是接受字符串作为键和字体作为对象。它是否正确?是否有一个不同的Collection子类更适合这样的东西?无论如何,请撕掉我的n00b Java。我需要学习这个。
package com.typeoneerror.apps.app_name.utils;
import android.content.Context;
import android.graphics.Typeface;
import java.util.Hashtable;
public class FontRegistry
{
private static FontRegistry _instance;
private Context _context;
private Hashtable<String, Typeface> _fonts;
private FontRegistry()
{
_fonts = new Hashtable<String, Typeface>();
}
public static FontRegistry getInstance()
{
if (_instance == null)
{
_instance = new FontRegistry();
}
return _instance;
}
public void init(Context context)
{
_context = context;
}
public Typeface getTypeface(int resourceId)
{
String fontName = _context.getResources().getString(resourceId);
if (!_fonts.containsKey(fontName))
{
String fontPath = "fonts/" + fontName;
Typeface typeface = Typeface.createFromAsset(_context.getAssets(), fontPath);
_fonts.put(fontName, typeface);
}
return (Typeface)_fonts.get(fontName);
}
}
答案 0 :(得分:7)
给你两个建议。
首先,变量类型应该引用Map的接口。这为您的未来提供了更大的灵活性,并且可以与大多数其他Java开发人员更好地融合。
其次,实现应该是HashMap,而不是HashTable。 HashTable会同步所有内容,而HashMap则不会。
如果您确实需要多线程访问,我建议使用ConcurrentHashMap而不是HashTable。 ConcurrentHashMap表现更好,因为它在访问期间不会锁定整个地图。
所以,
private Map<String, Typeface> _fonts;
和
_fonts = new HashMap<String, Typeface>();
最后,许多Java开发人员更愿意不使用下划线启动成员变量。虽然这是一个有争议的偏好。
编辑:最后的挑剔。您似乎使用单例模式进行注册表。这可能会在以后咬你,所以考虑避免单身http://accu.org/index.php/journals/337。但是,忽略这一点,你可能最好在声明中实例化单例静态实例。它可以避免在第一次获取时发生争用。
所以:
private static FontRegistry _instance = new FontRegistry;
答案 1 :(得分:1)
要扩展我的评论,getInstance()
的实现不是线程安全的。如果你真的必须使用Singleton模式,你可以使用“Bill Pugh”版本(我公开复制了wikipedia article):
public class Singleton {
// Private constructor prevents instantiation from other classes
private Singleton() {
}
/**
* SingletonHolder is loaded on the first execution of Singleton.getInstance()
* or the first access to SingletonHolder.INSTANCE, not before.
*/
private static class SingletonHolder {
public static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
此外,在为Android开发时,您需要小心,不要“泄漏”Context
。这是一个good article,为什么这样做很糟糕,以及如何避免它。底线是static
对Context
(或自身引用Context
的对象)的引用可能意味着您的Activity
实例无法进行垃圾回收。