Field::setLong class 中 Long 和 long 字段的行为不同
Field::setLong behave differently with Long and long fields in a class
我的代码有一个非常奇怪的问题。
当我 运行 它时,我得到异常:
Exception in thread "main" java.lang.IllegalArgumentException: Can not set java.lang.Long field lesson12.TestReflectionRepository.Main$TestSetLong.LongField to (long)23132
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167)
at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:195)
at java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.setLong(UnsafeObjectFieldAccessorImpl.java:120)
at java.base/java.lang.reflect.Field.setLong(Field.java:1021)
at lesson12.TestReflectionRepository.Main.main(Main.java:15)
我不明白这是什么意思。如果我对变量 l
使用类型 Long
,我也会在同一行得到相同的异常。我认为,这取决于 class、long
或 Long
中使用的是什么类型。但我认为,它不应该这样工作。
为什么会这样?我怎么了?
public class Main {
public static class TestSetLong {
public Long LongField;
public long longField;
}
public static void main(String[] args) throws Exception {
TestSetLong obj = new TestSetLong();
Class cobj = obj.getClass();
Field longField = cobj.getField("longField"), LongField = cobj.getField("LongField");
long l = 23132L;//if I use Long I also get this exception on the same line
longField.setLong(obj, l);
LongField.setLong(obj, l);
}
}
我在 Intellij IDEA 2021.2.3 中使用 OpenJDK 11.0.12+7-b1504.40 amd64,运行它。
根据 JavaDoc for Field
你可以:
- 使用
Field.set(Object, Object)
设置参考字段和原始字段
If the underlying field is of a primitive type, an unwrapping conversion is attempted to convert the new value to a value of a primitive type. If this attempt fails, the method throws an IllegalArgumentException.
- 仅使用
Field.setLong(Object, long)
设置(原始)类型的字段 long
Sets the value of a field as a long
on the specified object. This method is equivalent to set(obj, lObj), where lObj is a Long object and lObj.longValue() == l.
请注意,此描述提到了 set(Object, Object)
中发生的自动展开 - 但它没有任何地方暗示可能允许自动换行。
我的代码有一个非常奇怪的问题。 当我 运行 它时,我得到异常:
Exception in thread "main" java.lang.IllegalArgumentException: Can not set java.lang.Long field lesson12.TestReflectionRepository.Main$TestSetLong.LongField to (long)23132 at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:167) at java.base/jdk.internal.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:195) at java.base/jdk.internal.reflect.UnsafeObjectFieldAccessorImpl.setLong(UnsafeObjectFieldAccessorImpl.java:120) at java.base/java.lang.reflect.Field.setLong(Field.java:1021) at lesson12.TestReflectionRepository.Main.main(Main.java:15)
我不明白这是什么意思。如果我对变量 l
使用类型 Long
,我也会在同一行得到相同的异常。我认为,这取决于 class、long
或 Long
中使用的是什么类型。但我认为,它不应该这样工作。
为什么会这样?我怎么了?
public class Main {
public static class TestSetLong {
public Long LongField;
public long longField;
}
public static void main(String[] args) throws Exception {
TestSetLong obj = new TestSetLong();
Class cobj = obj.getClass();
Field longField = cobj.getField("longField"), LongField = cobj.getField("LongField");
long l = 23132L;//if I use Long I also get this exception on the same line
longField.setLong(obj, l);
LongField.setLong(obj, l);
}
}
我在 Intellij IDEA 2021.2.3 中使用 OpenJDK 11.0.12+7-b1504.40 amd64,运行它。
根据 JavaDoc for Field
你可以:
- 使用
Field.set(Object, Object)
设置参考字段和原始字段
If the underlying field is of a primitive type, an unwrapping conversion is attempted to convert the new value to a value of a primitive type. If this attempt fails, the method throws an IllegalArgumentException.
- 仅使用
Field.setLong(Object, long)
设置(原始)类型的字段long
Sets the value of a field as a
long
on the specified object. This method is equivalent to set(obj, lObj), where lObj is a Long object and lObj.longValue() == l.
请注意,此描述提到了 set(Object, Object)
中发生的自动展开 - 但它没有任何地方暗示可能允许自动换行。