目前正在尝试使Java驱动程序与Scala案例类兼容。问题是反思失败了。
基本上,很多不需要的字段都会出现,并且会插入ANNOTATION
和getModifiers
等字段。但是,当我使用调试器进行检查时,下面代码中的pojo
确实是models.User
。但是,在getClass()
上调用pojo
会产生java.lang.Class
。
我还尝试在案例类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
感谢您的帮助!
答案 0 :(得分:0)
您列出了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))
)
}
爪哇:
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}