Java不少类可以通过Set方法动态向对象添加新的字段内容,这里面如何实现这功能且代码质量较高呢?这里我参照thinking in java的书籍,自定义一个可以在运行时动态的添加字段内容。
//自定义异常
class DynamicFieldsException extends Exception {}
public class DynamicFields
{
private Object[][] fields;
//初始化保存字段内容的数组
public DynamicFields(int initialSize)
{
fields=new Object[initialSize][2];
for(int i=0;i<fields.length;i++)
{
fields[i]=new Object[]{null,null};
}
}
//输出内容
@Override
public String toString()
{
StringBuilder result=new StringBuilder();
for(Object[] filed:fields)
{
result.append(filed[0]);
result.append(":");
result.append(filed[1]);
result.append("\n");
}
return result .toString();
}
//查询该字段内容是否已存在
private int hasField(String id)
{
for(int i=0;i<fields.length;i++)
{
if(id.equals(fields[i][0]))
return i;
}
return -1;
}
private int getFieldNumber(String id) throws NoSuchFieldException
{
int fieldNum=hasField(id);
if(fieldNum==-1)
throw new NoSuchFieldException();
return fieldNum;
}
private int makeField(String id)
{
for(int i=0;i<fields.length;i++)
{
if(fields[i][0]==null)
{
fields[i][0]=id;
return i;
}
}
//如果数组内存已满,则重新开辟一个内存更大的数组,这里我只加一个字段内存
Object[][] objects=new Object[fields.length+1][2];
//拷贝字段内容
for(int i=0;i<fields.length;i++)
{
objects[i]=fields[i];
}
for(int i=fields.length;i<objects.length;i++)
{
objects[i]=new Object[]{null,null};
}
//赋给新开辟数组内存的引用地址
fields=objects;
return makeField(id);
}
public Object getField(String id)throws NoSuchFieldException
{
return fields[getFieldNumber(id)][1];
}
public Object setField(String id,Object value)throws DynamicFieldsException
{
if(value==null)
{
DynamicFieldsException fieldsException=new DynamicFieldsException();
//保留最原始异常信息
fieldsException.initCause(new NullPointerException());
throw fieldsException;
}
int fieldNumber=hasField(id);
if(fieldNumber==-1)
{
fieldNumber=makeField(id);
}
Object result=null;
try
{
//获取原来的字段内容
result=getField(id);
} catch (NoSuchFieldException e)
{
//保留原来异常信息
throw new RuntimeException(e);
}
//更新字段内容
fields[fieldNumber][1]=value;
return result;
}
public static void main(String[] args)
{
DynamicFields df = new DynamicFields(3);
System.out.println(df);
try
{
df.setField("d", "A value for d");
df.setField("number", 47);
df.setField("number2", 48);
System.out.println(df);
df.setField("d", "A new value for d");
df.setField("number3", 11);
System.out.println("df: " + df);
System.out.println("df.getField(\"d\") : " + df.getField("d"));
//这里将会抛出异常
Object field = df.setField("d", null);
} catch(NoSuchFieldException e)
{
e.printStackTrace(System.out);
} catch(DynamicFieldsException e)
{
e.printStackTrace(System.out);
}
}
}
运行结果:
null:null
null:null
null:null
d:A value for d
number:47
number2:48
df: d:A new value for d
number:47
number2:48
number3:11
df.getField("d") : A new value for d
beyondboy.DynamicFieldsException
at beyondboy.DynamicFields.setField(DynamicFields.java:80)
at beyondboy.DynamicFields.main(DynamicFields.java:119)
Caused by: java.lang.NullPointerException
at beyondboy.DynamicFields.setField(DynamicFields.java:82)
... 1 more