Java:将具有不同类型的参数传递给函数

Posted

技术标签:

【中文标题】Java:将具有不同类型的参数传递给函数【英文标题】:Java: passing an argument with a different type to a function 【发布时间】:2012-10-27 23:27:28 【问题描述】:

在 Java 中,假设我们有一个带有参数double a 的函数。如果我将整数作为参数传递,它会起作用吗? (我的意思是,是否存在隐式转换?)在相反的情况下:如果我有例如一个整数作为参数,我传递一个双精度数?

不幸的是,我现在无法编译我的代码,我想检查一下这个断言。 感谢您的关注。

【问题讨论】:

传递一个 int 而不是一个 double,很好。传递浮点数而不是双精度数,很好。通过双而不是其中任何一个?不不不。 我希望 Java 在这方面会更加“灵活”... :) 【参考方案1】:

有关Method Invocation Conversion 的详细信息,请参阅JLS - Section # 5.3。

方法调用上下文允许使用以下之一:

- an identity conversion (§5.1.1)
- a widening primitive conversion (§5.1.2)
- a widening reference conversion (§5.1.5)
- a boxing conversion (§5.1.7) optionally followed by widening reference conversion
- an unboxing conversion (§5.1.8) optionally followed by a widening primitive conversion.

因此,您的第一次调用(intdouble)将根据 规则 #2 正常工作。

但第二次调用(doubleint)将给出编译器错误,根据同一部分中进一步引用的声明:-

如果表达式的类型不能转换为 方法调用上下文中允许的转换参数, 然后发生编译时错误。

【讨论】:

谢谢大家的回答!【参考方案2】:

因为您可以将双精度设置为整数,所以整数作为参数可以使用双精度作为参数。其他方式失败。在这种情况下,您需要将 double 类型转换为 int。同样适用于普通的分配,例如..

  int i = 6;
  double d = 0;
  d = i;  /* ok
  i = d ; /* not ok

【讨论】:

【参考方案3】:

您有时可以通过使您的函数采用Number 的参数来解决此问题。这是IntegerDouble 都继承自的对象,因此直到Double 数字和Integer 数字的行为相同,这将起作用。

请注意,原语integerdouble 与对象IntegerDouble 之间存在差异。 Java 使用自动装箱在函数调用等中自动转换这些类型。

【讨论】:

是的,这将根据rule # 4 工作。注意装箱后不能从Integer扩大到Double,因为它不是Integer的超类型,你必须使用Number【参考方案4】:

最初原始扩展会发生在原始类型上。 比如你想调用

 int input = 5; //int variable;
 apply(input); //calling method with int value. 

但是您的类不包含参数接受 int 的方法,因此编译器将使用 原始扩展。它将检查是否存在 java long 参数的任何 apply 方法。如果存在,将调用该方法。如果不是,它将检查 apply 是否存在 float 参数,然后将其选中。如果也没有找到它,它将寻找带有 double 参数的 apply

public void apply(long input) 
    System.out.println("long");   // first pick by the compiler.

public void apply(float input) 
    System.out.println("float"); // if above method not found this will be selected.

public void apply(double input) 
    System.out.println("double"); // above two methods not present this will be selected.

接下来,如果以上三个方法都没有找到,那么编译器将寻找 Autoboxing this 并尝试将其转换为相应的包装器。 int 是它的 java.lang.Integer。所以它会使用 Integer 参数检查 apply。如果这个找到的编译器会执行这个方法。

public void apply(Integer input) 
    System.out.println("Integer");

最后,如果以上都不存在,编译器会查找名称为 apply 且接受 int...Integer... 的任何方法> 并调用该方法。

public void apply(int... input) 
    System.out.println("int...");

如果你的类只包含以下两种方法

public void apply(long input) 
    System.out.println("long");

public void apply(float input) 
    System.out.println("float");

如果你想向这个方法传递一个 double 值,它不会编译。

double input = 5d;
apply(input); 
// The method apply(long) in the type YourClass 
//is not applicable for the arguments (double

如果您想完成这项工作,您必须将其类型转换为您的方法可以接受的内容。

apply((int) input);

然后编译器将尝试通过精确类型或原始扩展或自动装箱或数组匹配方式找到匹配项。

【讨论】:

以上是关于Java:将具有不同类型的参数传递给函数的主要内容,如果未能解决你的问题,请参考以下文章

将模板参数传递给调用成员函数的函数

将不同类型的参数传递给jdbctemplate查询

将具有类型参数的类作为Java中泛型方法的类型参数传递

将表值参数传递给具有不同字段数的存储过程

如何迭代地将参数传递给 R 函数

我可以将数组作为参数传递给 Java 中具有可变参数的方法吗?