目前正在尝试使Java驱动程序与Scala案例类兼容。问题是反思失败得很厉害。
基本上,许多不需要的字段正在通过,并且像ANNOTATION
和getModifiers
这样的字段正在被插入。但是,当我使用调试器进行检查时,下面代码中的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}