【问题标题】:Sending nulls as parameters to methods in Java将空值作为参数发送到 Java 中的方法
【发布时间】:2015-05-05 18:28:53
【问题描述】:

我在下面有一个相当简单的测试用例。我可以毫无问题或错误地将空值发送到构造函数,但是当我尝试将空值发送到方法时,它会出错:error: incompatible types: <null> cannot be converted to int(或任何预期的类型)。我不确定为什么会发生这种情况,而且我在很多地方都看到发送空值是可以接受的做法。实际上,我只需要空值,以便我可以将此示例泵入 Soot 和 Spark 进行静态分析,因此发送到方法的实际参数与 Spark 静态分析中入口点的语义必要性无关。

public class Test {
    public Test(Object var1, Object var2) {
        //do irrelevant stuff here with var1 and var2
    }

    public void api1(int x, int y) {
        // do irrelevant stuff with x and y
    }

    public List<String> api2(String x, int y, boolean a) {
        // do irrelevant stuff with x, y, and a and return a new ArrayList<String>()
    }
}

public class Main {
    public static void main(String[] args) {
        Test usingVars = new Test(1, 2);  // works, compiles and no errors
        Test usingNulls = new Test(null, null); // works, compiles and no errors

        /**
         * usingVars will obviously work and not complain at all
         */
        usingVars.api1(1, 2); // works, compiles and no errors
        usingVars.api2("test", 1, false); // works, compiles and no errors

        /**
         * usingNulls should work, but throws this error on compilation:
         *     error: incompatible types: <null> cannot be converted to int
         */
        usingNulls.api1(null, null); // should work, doesn't compile errors out
        usingNulls.api2(null, null, null); // should work, doesn't compile errors out

    }
}

【问题讨论】:

  • nullint 的类型不同。 int 之类的原语不能是 null
  • 对于您的Test(null, null),您必须有第二个接受对象的双参数构造函数。正如其他人所说,原语不能设置为空。如果要将 int 设置为默认状态,请将其值设为 0 并检查。
  • 我不确定您是否使用了您认为与new Test( null, null) 一起使用的构造函数。 int 是原始类型,不能设置为 null。看看是否有另一个构造函数接受某种对象作为参数;那就是你正在使用的那个。
  • 我编辑了代码以更恰当地反映我正在使用的 API。它们在构造函数中有可为空的对象。
  • 我相信您通过将 int 作为对象传递所做的事情是在堆上创建给定 int 内容的盒装副本。这可能不是您想要实现的目标。如果你需要一个构造函数有两个整数,最好是具体的,否则你可能会遇到意想不到的结果。

标签: java methods null parameter-passing static-analysis


【解决方案1】:

基元(例如ints)不能采用nulls。如果您绝对必须使用null 值,您应该将您的方法参数定义为适当的包装类(例如,java.lang.Integer 代表int):

public Test(Integer var1, Integer var2) {
    //do irrelevant stuff here with var1 and var2
}

public void api1(Integer x, Integer y) {
    // do irrelevant stuff with x and y
}

public List<String> api2(String x, Integer y, Boolean a) {
    // do irrelevant stuff with x, y, and a and return a new ArrayList<String>()
}

【讨论】:

  • 不确定是否添加传递 null 的功能显然是无效的。
  • 我没有向API添加非原始参数的选项,API是android源代码。但是,由于我设计 API 枚举器的方式,简单地向 api 调用添加一个原始值对我来说是微不足道的。我实际上并没有使用 API,至少不是人们想的那样。我的 main 仅用于生成调用图。所以我发送的关于参数的方法与 API 本身完全无关。
  • 我最终只是将我的逻辑从不分青红皂白地将所有内容都设为 null 更改为:if(number-based primitive){1}else if(boolean){false}else if(char){"a"}else{null} 足够简单。谢谢。
【解决方案2】:

在 Java 中,您有两种类型的变量,原语和引用。

引用可以是null,因为它不引用任何内容。原语,例如int 不能是null,它必须是一个数字。

如果您不关心值是什么,您可以使用 0-1Integer.MIN_VALUE

【讨论】:

    【解决方案3】:

    不可能将 null 传递给方法、构造函数或其他方式,传递给原始类型(例如 intshortbytefloat),因为在 java 中有两种类型系统,基元和对象。基元可以转换为它们的对象包装器(例如IntegerShortByteFloat)并用作对象,因此如果您需要传递 null,请使用 @987654330 @,不是int。然而,Java 中为ints 传递无用值的约定是使用-1

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多