0

我最近遇到了以下错误,这让我很困惑。我已经导入了反射。我有一个类(称为工人),其字段是一个名为 numOfJobs 的私有 int。在 Worker 的构造函数中,numOfJobs 设置为 0。然后,在测试器类中,我创建了一个 worker 类型的实例:

    waterBenders[0] = new Worker();
    Field []fields = waterBenders[0].getClass().getDeclaredFields();
    Field privateFieldJobs = fields[0];
    privateFieldJobs.setAccessible(true);

    try{

          System.out.println(privateFieldJobs.get(waterBenders[0]));

          System.out.println(privateFieldJobs.get(waterBenders[0]).getClass());

          System.out.println((int)privateFieldJobs.get(waterBenders[0]));
    }

这是包含错误的尝试框中的第三行。前两行打印:

    0    
    class java.lang.Integer

这对我来说很有意义。但是,如果对象 privateFieldJobs.get(waterBenders[0]) 是“值”为 0 的 Integer 类型的对象,那么为什么 (int)privateFieldJobs.get(waterBenders[0]) 会抛出错误:

    Cannot cast from java.lang.Object to int

如果我要创建一个整数类型的普通对象,那么这种类型的转换通常可以工作。这个例子有什么特别之处?我想这与这个 Integer 对象来自 fields 数组的事实有关。

我的工人阶级本质上是:

    public class Worker extends Unit{
      private int numOfJobs;

      public Worker(Tile position, double hp, String faction) {
        super(position, hp, 2, faction);   
        this.numOfJobs = 0;
      }

      public int getNumOfJobs(){
        return this.numOfJobs;
      }
    }

任何帮助,将不胜感激。

4

2 回答 2

2

基本上你正在尝试这个:

Integer i=1;
Object o=i;
int val=(int)o;

它没有理由工作,这就是为什么它不工作。

要么将其转换回Integer(如您所见, a 不需要println,因为无论如何都会调用正确toString()的,但拆箱需要它),或者您可以尝试使用getInt()

int val1=(Integer)privateFieldJobs.get(waterBenders[0]);
int val2=privateFieldJobs.getInt(waterBenders[0]);


好吧,我对后者是错误的:虽然他们都为 an 工作int,但getInt()在 an 上不起作用Integer

import java.lang.reflect.*;

class Ideone {
    public Integer objInt=23;
    public int valInt=42;

    public static void main (String[] args) throws java.lang.Exception {
        Field objField=Ideone.class.getField("objInt");
        Field valField=Ideone.class.getField("valInt");

        Ideone test=new Ideone();

        System.out.print("objInt-get: ");
        System.out.println(objField.get(test));

        System.out.print("objInt-getInt: ");
        try{
            System.out.println(objField.getInt(test));
        } catch (Exception ex) {
            System.out.println(ex.getClass());
        }

        System.out.print("valInt-get: ");
        System.out.println(valField.get(test));

        System.out.print("valInt-getInt: ");
        System.out.println(valField.getInt(test));
    }
}

(类被称为Ideone,因为它可以在那里尝试:https ://ideone.com/91xzmc )
输出:

objInt-get: 23
objInt-getInt: class java.lang.IllegalArgumentException
valInt-get: 42
valInt-getInt: 42

因此,可以在一个字段上同时使用get()和,但是当该字段为 时,只能获得作品。(魔术只是缩短消息,默认情况下有一个很长的解释,不适合一行)。getInt()intIntegerex.getClass()

旁注:数字类的使用,如Integer,意味着在堆上创建对象(这会增加堆碎片,并且可以为垃圾收集器做额外的工作)。如果您不需要一个数字来实现null,或者出于任何其他原因成为对象(一些奇异的序列化程序可能需要它),请使用int. 它的打字速度更快、更轻、甚至更短,而且无需触摸Shift(for I)。

于 2019-10-02T20:26:36.510 回答
2

这是因为 Field#get 返回一个 Object,并且您不能将任何 Object 类型转换为 java 中的原始类型。如果你想要一个 Integer 对象的原始整数值,你可以做这样的事情

Integer field = (Integer) privateFieldJobs.get(waterBenders[0]);
int value = field.intValue();
于 2019-10-02T20:02:08.170 回答