Scala 2.11 case类的Java反射返回未声明的字段



目前正在尝试使Java驱动程序与Scala案例类兼容。问题是反思失败得很厉害。

基本上,许多不需要的字段正在通过,并且像ANNOTATIONgetModifiers这样的字段正在被插入。但是,当我使用调试器进行检查时,下面代码中的pojo实际上是models.User。然而,在pojo上调用getClass()会生成java.lang.Class

我还尝试过在case类val中创建每个字段,然后在该类上调用.getDeclaredFields(),但效果相同。

知道为什么会发生这种事吗?这是Java代码:

private static Map<String, Object> toMap(Object pojo) {
    try {
        Map<String, Object> map = new HashMap<>();
        Class pojoClass = pojo.getClass();
        if (!Modifier.isPublic(pojoClass.getModifiers())) {
            throw new IllegalAccessException(String.format("%s's class should be public", pojo));
        }
        for (Field field : pojoClass.getDeclaredFields()) {
            System.out.println(field.toString());
        }
        for (Field field : pojoClass.getDeclaredFields()) {
            field.setAccessible(true);
            if (field.getDeclaringClass() == pojoClass) {
                Object value = field.get(pojo);
                if (value instanceof Integer) {
                    throw new IllegalAccessException(String.format(
                            "Make %s of %s Long instead of Integer", field.getName(), pojo));
                }
                map.put(field.getName(), value);
            }
        }
        return map;
    }
    catch (IllegalAccessException e) {
        throw new ReqlDriverError("Can't convert %s to a ReqlAst: %s", pojo, e.getMessage());
    }
}

以下是我的Scala案例类:

case class User(
  userId: String,
  loginInfo: LoginInfo,
  firstName: Option[String],
  lastName: Option[String],
  fullName: Option[String],
  email: Option[String],
  avatarURL: Option[String]) extends Identity

如果我迭代getDeclaredFields(),我会得到以下结果:

ANNOTATION
ENUM
SYNTHETIC
cachedConstructor
newInstanceCallerCache
name
allPermDomain
useCaches
reflectionData
classRedefinedCount
genericInfo
serialVersionUID
serialPersistentFields
reflectionFactory
initted
enumConstants
enumConstantDirectory
annotationData
annotationType
classValueMap

谢谢你的帮助!

您正在列出Class:的字段

scala> classOf[Class[_]].getDeclaredFields
res4: Array[java.lang.reflect.Field] = Array(private static final int java.lang.Class.ANNOTATION, private static final int java.lang.Class.ENUM, private static final int java.lang.Class.SYNTHETIC, private transient volatile java.lang.reflect.Constructor java.lang.Class.cachedConstructor, private transient volatile java.lang.Class java.lang.Class.newInstanceCallerCache, private transient java.lang.String java.lang.Class.name, private static java.security.ProtectionDomain java.lang.Class.allPermDomain, private static boolean java.lang.Class.useCaches, private transient volatile java.lang.ref.SoftReference java.lang.Class.reflectionData, private transient volatile int java.lang.Class.classRedefinedCount, private transient volatile sun.reflect.generics.repository.ClassRepository java.lang.C...

我不知道Identity是什么。

Scala:

package ccreflect
case class User(
  userId: String,
  loginInfo: String,
  firstName: Option[String],
  lastName: Option[String],
  fullName: Option[String],
  email: Option[String],
  avatarURL: Option[String])
object Test extends App {
  Console println runtime.ScalaRunTime.stringOf(
    Util.toMap(User("Bob", "xxx", None, None, None, None, None))
  )
}

Java:

package ccreflect;
import java.util.Map;
import java.util.HashMap;
import java.lang.reflect.*;

public class Util {
public static Map<String, Object> toMap(Object pojo) {
    try {
        Map<String, Object> map = new HashMap<>();
        Class pojoClass = pojo.getClass();
        if (!Modifier.isPublic(pojoClass.getModifiers())) {
            throw new IllegalAccessException(String.format("%s's class should be public", pojo));
        }
        for (Field field : pojoClass.getDeclaredFields()) {
            System.out.println(field.toString());
        }
        for (Field field : pojoClass.getDeclaredFields()) {
            field.setAccessible(true);
            if (field.getDeclaringClass() == pojoClass) {
                Object value = field.get(pojo);
                if (value instanceof Integer) {
                    throw new IllegalAccessException(String.format(
                            "Make %s of %s Long instead of Integer", field.getName(), pojo));
                }
                map.put(field.getName(), value);
            }
        }
        return map;
    }
    catch (IllegalAccessException e) {
        throw new RuntimeException(String.format("Can't convert %s to a ReqlAst: %s", pojo, e.getMessage()));
    }
}
}

结果

$ scala ccreflect.Test
private final java.lang.String ccreflect.User.userId
private final java.lang.String ccreflect.User.loginInfo
private final scala.Option ccreflect.User.firstName
private final scala.Option ccreflect.User.lastName
private final scala.Option ccreflect.User.fullName
private final scala.Option ccreflect.User.email
private final scala.Option ccreflect.User.avatarURL
{firstName=None, lastName=None, avatarURL=None, loginInfo=xxx, fullName=None, userId=Bob, email=None}

相关内容

  • 没有找到相关文章

最新更新