Java 高效地获取对象';s属性或强制声明类属性
背景设置 我试图在Android中创建一个用于访问和缓存web服务数据的库,但偶然发现了一个问题Java 高效地获取对象';s属性或强制声明类属性,java,android,static,key-value-coding,kvc,Java,Android,Static,Key Value Coding,Kvc,背景设置 我试图在Android中创建一个用于访问和缓存web服务数据的库,但偶然发现了一个问题 我的库管理的所有对象都继承自一个基本实体类。实体的任何派生类都可以声明其他字段*或属性* 基类负责返回要从缓存(SQLite或文件)或web服务(REST或SOAP)读取的实体属性。在我当前的实现中,实体类使用反射执行此操作:它读取用@属性注释标记的所有类字段名 问题 我在实现中遇到的问题如下:每次我使用类似于static Set getAttributes()的函数请求所有实体的属性时,此函数必须
我的库管理的所有对象都继承自一个基本
实体
类。实体
的任何派生类都可以声明其他字段*或属性*
基类负责返回要从缓存(SQLite或文件)或web服务(REST或SOAP)读取的实体
属性。在我当前的实现中,实体
类使用反射执行此操作:它读取用@属性
注释标记的所有类字段名
问题
我在实现中遇到的问题如下:每次我使用类似于static Set getAttributes()
的函数请求所有实体的属性时,此函数必须创建Set
实现(目前使用HashSet
进行快速查找)
我希望避免每次请求所有属性时都分配和初始化集合
在我看来,属性集是特定于整个实体
类的,而不是实体
对象。即:拥有类客户扩展实体
,所有客户
实例都具有相同的确切属性-每个实例都有一个名称、地址等
我目前的尝试是在扩展实体的每个类中声明静态集属性
,并使用类'静态
块中的反射初始化该集
,如下所示:
class Customer extends Entity
{
private static final Set<String> attributes = new HashSet<String>();
static
{
Entity.populateAttributes(Customer.class);
}
}
class客户扩展实体
{
私有静态最终集属性=新HashSet();
静止的
{
实体.populateAttribute(Customer.class);
}
}
给定要初始化的类,实体
类可以查找该类及其基类中标记有@属性
注释的所有字段(例如,Customer extends Person
和Person extends Entity
将使用为Customer
类声明的属性和从Person
类继承的属性填充Customer.attributes
集)
我遇到的问题是,属性
集合可能没有为扩展了实体
的类定义,我希望在编译时强制执行
我已经看到Eclipse中的Serializable
接口实现了这一点:当创建实现Serializable
的类时,如果您的类没有声明[private]静态最终长serialVersionUID
,Eclipse将显示一条警告
问题
如果类没有声明字段,是否有任何方法可以对我的实体类强制执行可序列化的行为,并显示警告或(更好的)错误
是否有不同的方法返回实体
派生类的属性名称
脚注
*我使用术语字段
表示不应由库管理的对象属性,使用术语属性
表示应由库管理的对象属性(从web服务或SQLite/文件缓存读取,并保存在web服务或SQLite/文件缓存中)
编辑1
基本上,我试图实现的是以高效的方式获取一组实体的属性*(参见上面的脚注)。帮助器类使用此列表将对象值存储在数据库中(可以从属性名称和类型推断创建表
查询)或发送到web服务
此库用于缓存web服务中的值和同步本地数据库(可能包含额外的用户输入值,并且可能缺少对象的服务器更新值)通过web服务访问数据。它不打算用通用访问器/变异器替换应用程序中的每字段访问器/变异器
这个概念被称为键值编码,被许多框架和库使用。例如,我在谷歌搜索中发现的使用KVC的前两个库示例是Cocoa和Sproutcore。参考文献:和
KVC也用于Android开发。Bundle
、SQLiteCursor
和ContentValues
大量使用KVC。由于我可能无法在派生类的定义中强制声明静态字段,我将在t的定义中存储属性集和类描述的映射创建上述实体
类,并确保派生类的属性集在实体
构造函数中初始化
例如:
public class Entity
{
private final static Map<Class<? extends Entity>, Set<String>> attributes = new HashMap<Class<? extends Entity>, Set<String>>();
public static void populateAttributes(Class<? extends Entity> derivedClass)
{
//initialize the set of attributes for the derived class and
//add it to attributes map with "derivedClass" as key
}
static
{
populateAttributes(Entity.class);
}
public Entity()
{
//calling this.getClass() returns the object's actual (derived) class(*)
if(!attributes.containsKey(this.getClass())
populateAttributes(this.getClass());
}
//rest of class definition (including getAttributes method)
}
public class Customer extends Entity
{
@Attribute
String someAttribute; //will be processed automatically
}
公共类实体
{
private final static Map“我的库管理的所有对象都从基本实体类继承。实体的任何派生类都可以声明其他字段*或属性*”也许这就是问题的核心。为什么不像其他人一样使用数据成员、getter和setter呢?为什么要尝试在Java之上构建自己的二流编程语言呢?我这样做是为了让处理对象到数据源的序列化/反序列化的类能够做到这一点,而不必永远修改y实体
添加到应用程序中。另外,另一种方法是(如果我将序列化/反序列化责任转移到实体
类):我希望能够将序列化/反序列化类从JSON REST-ful服务切换到SOAP或XML REST-ful服务,而无需修改