Java 高效地获取对象';s属性或强制声明类属性

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()的函数请求所有实体的属性时,此函数必须

背景设置

我试图在Android中创建一个用于访问和缓存web服务数据的库,但偶然发现了一个问题


我的库管理的所有对象都继承自一个基本
实体
类。
实体
的任何派生类都可以声明其他字段*或属性*

基类负责返回要从缓存(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服务,而无需修改