I have one very strange problem with my code. When I run it, I get exception:
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)
I don't understand what it means. If I use type Long
for the variable l
I also get the same exception on the same line. I think, it depends on what type is used in the class, long
or Long
. But I think, it shouldn't work like this.
Why does it happen? What's wrong I do?
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);
}
}
I use OpenJDK 11.0.12+7-b1504.40 amd64, run it in Intellij IDEA 2021.2.3.
According to the JavaDoc for Field
you can:
Field.set(Object, Object)
to set reference field and primitive fieldsIf 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)
only to set fields of (primitive) type 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.
Note that this description mentions the automatic unwrapping that occurs in set(Object, Object)
- but it nowhere gives a hint that automatic wrapping might be allowed.