Android Java objModelClass.getClass()。getDeclaredFields()返回“$ change”作为一个字段

在我们的项目中,我们使用数据模型来存储从服务接收的数据。 所以在我们向数据库插入数据的特定情况下,我们使用objModelClass.getClass()。getDeclaredFields()方法来获取所有字段名称,并且正确返回了该的所有字段名称,但也返回了一个名称“$ change”,这在课堂上是不存在的。

奇怪的是,在android工作室没有这样的问题,但是当我们升级到android studio 2.0这发生。

虽然我已经应用了一个快速修复,但我需要妥善解决这个问题。 我想知道为什么发生?

这个函数使用这个方法

public void insertValuesIntoTable(final String strTableName, ArrayList<Object> alObjClasses, String strPrimaryKey, String strCompositeKey) { try { SQLiteDatabase db_w = this.getWritableDatabase(); ContentValues contentValues = new ContentValues(); //Iterate through every model class Object in the ArrayList and transfer the contents to the DB if (alObjClasses != null) for (Object objModelClass : alObjClasses) { for (Field field : objModelClass.getClass().getDeclaredFields()) { //Encrypt value if encryption is enabled & the column is to be encrypted try { field.setAccessible(true); //Test if the table received is Ignore contacts. Minor Hack inserted //So that the same contact data model can be re used. It checks if the //Table is of ignored constant or not then checks if the column exists //in the table or not as that of the field name. Doing this saves //from receiving a SQLConstraint exception stating, "Column not found" if(field.getName().equals("$change")) continue; if(strTableName.equalsIgnoreCase(ContactConstants.TABLE_IGNORED_CONTACTS)) if(!field.getName().equalsIgnoreCase(ContactConstants.TABLE_IGNORED_CONTACTS_NAMES) && !field.getName().equalsIgnoreCase(ContactConstants.TABLE_IGNORED_CONTACTS_NUMBERS) && !field.getName().equalsIgnoreCase(ContactConstants.TABLE_IGNORED_CONTACTS_EMAIL) && !field.getName().equalsIgnoreCase(ContactConstants.TABLE_IGNORED_CONTACTS_CITY) && !field.getName().equalsIgnoreCase(ContactConstants.TABLE_IGNORED_CONTACTS_ID)) continue; contentValues.put(field.getName(), (Constants.ENCRYPTION_PREFERENCE && HelperFunctions.isColumnEncrypted(field.getName())) ? HelperFunctions.encryptString((String) field.get(objModelClass)) : (String) field.get(objModelClass)); } catch (IllegalAccessException e) { // e.printStackTrace(); //Never thrown since field.setAccessible(true); is called before accessing data } catch ( ClassCastException e) { // e.printStackTrace(); //Never thrown since field.setAccessible(true); is called before accessing data } } try { if (db_w.insert(strTableName, null, contentValues) == -1) throw new SQLiteConstraintException(); } catch (SQLiteConstraintException e) { // e.printStackTrace(); Log.i("Error - DB", "Error occurred while trying to add data to " + strTableName + " Table, updating data instead."); //Since the entry exists in the DB, it will be updated instead updateEntryInDatabase(db_w, strTableName, strPrimaryKey, strCompositeKey, contentValues); } } db_w.close(); } catch (NullPointerException e) { // e.printStackTrace(); //Is thrown sometimes when the context of the activity which called it is destroyed mid execution } catch (SQLiteException e) { // e.printStackTrace(); //Is thrown sometimes when the context of the activity which called it is destroyed mid execution } } 

Solutions Collecting From Web of "Android Java objModelClass.getClass()。getDeclaredFields()返回“$ change”作为一个字段"

自今天上午以来,我一直在努力解决这个问题。 这是由于Android Studio 2即时运行的新function,它在某处添加了这个字段,因为它可能在debugging时看到:它实现了com.android.tools.fd.runtime.IncrementalChange接口。

这个问题可以通过使用isSynthetic()方法检查字段来解决:它将对运行时生成的字段(如$change isSynthetic()返回true ,否则返回false

我想知道为什么发生?

您的项目已经在2.0之前的Android Studio中构build,因此无法使用Android Studio 2.0中引入的即时运行

我需要妥善解决这个问题

您可以使用以下方法解决此问题:运行>清理并重新运行,来源: https : //developer.android.com/studio/run/index.html#rerun

或通过:

  1. 禁用即时运行:文件>设置>构build,执行,部署>即时运行,并取消选中启用即时运行
  2. 运行该项目
  3. 启用即时运行:文件>设置>构build,执行,部署>即时运行,然后选中启用即时运行