当前位置: 首页 > 面试题库 >

用变量参数重载方法(变量)

訾高明
2023-03-14
问题内容

看到以下代码的输出,我感到很惊讶:

public class File
{
    public static void main(String[] args)
    {
        movie();
    }

    static void movie(double... x)
    {
        System.out.println("No varargs");
    }

    static void movie(int... x)
    {
        System.out.println("One argument");
    }
}

它输出

One argument

为什么会这样呢?

我以为该代码不会编译,因为对的调用movie() 模棱两可的 ,但它运行良好并可以输出One argument

如果我将代码修改为:

public class File
{
    public static void main(String[] args)
    {
        movie();
    }

    static void movie(boolean... x)  //Changed the parameter type to boolean from double
    {
        System.out.println("No varargs");
    }

    static void movie(int... x)
    {
        System.out.println("One argument");
    }
}

没有错误消息

为什么第一个代码可以正常运行,但是第二个却给出错误?


问题答案:

此行为是由于与和之间没有这种比较相比,int它更具体。double``int``boolean

如JLS
第15.12.2.5节(强调我的)中所述:

如果满足以下任一条件,则使用参数表达式e1,…,ek进行调用时,一个适用的方法m1 比另一适用的方法m2 更具体

  • m2不是通用的,并且 m1和m2可通过可变arity调用应用
    ,并且其中m1的前k个可变arity参数类型为S1,…,Sk,而m2的前k个可变arity参数类型为T1,…。 。,TK,
    该型Si比的Ti更加具体 为参数EI对于所有的i(1≤I≤K)。另外,如果m2具有k + 1个参数,则m1的第k +
    1个可变稀疏参数类型是m2的第k + 1个可变稀疏参数类型的子类型。


什么 更具体的
,其实就是在后文中定义的子类型:

如果S <:T,则对于任何表达式,类型S比类型T更具体。

这意味着,S是更具体的比TS是的子类型T。对于基本类型,这归结为以下属性:

  • 双>浮动
  • 浮动>长
  • 长>整数
  • 整数>字符
  • int>短
  • 短>字节

注意那boolean不存在。

因此,

public static void main(String[] args) {
    movie();
}

static void movie(int... x) { }
static void movie(short... x) { }
static void movie(double... x) { }
static void movie(byte... x) { }

编译并movie(byte... x)会被调用,因为它是最具体的。

然而,

public static void main(String[] args) {
    movie();
}

static void movie(int... x) { }
static void movie(boolean... x) { }

无法编译,因为boolean无法与进行比较int



 类似资料:
  • 问题内容: 嗨,我在理解上面代码的输出时遇到了麻烦。输出为: 我理解为什么gc.r是10。我也理解为什么gc.getR()是10(因为GraphicCircle中的getR()方法覆盖了Circle的getR()方法)。但是我不明白为什么cr是100,而c.getR()是10(我很难理解当您像上面的代码那样键入到祖先类时继承发生了什么)。 问题答案: 方法调用在Java中是 虚拟 的,这意味着将调

  • 问题内容: 该代码无法编译,编译器说f含糊。但是我认为第二种方法可以解决什么问题? 问题答案: 这是因为无法确定该方法调用是应调用变量args还是应调用float和变量args。 Java决定以这种方式来调用拓宽>装箱>变量args的方法,但是在这种情况下,两者都具有变量args。 在这种情况下,基本上将char扩展为浮动。 Java基元的扩展顺序为:

  • 从性能还是从其他因素来看,哪一种方法更好? 假设我正在创建一个类,其中有一个方法,它接受2个值并将它们相加在一起。 是有两个实例变量来存储两个值,然后有一个方法来使用这些值更好,还是在调用方法时将变量作为参数传入更好? 或者仅仅使用静态方法更好,这样我就不需要在每次使用该方法时创建对象了?

  • 对于变量和参数,不管是已经敲代码多年的老鸟,还是刚刚接触编程的小白,都会有时候清楚,有时候又有点模糊。因为,在实际应用中,它们之间分分离离,比如,敲代码都知道,x=3中x是变量,它不是参数,但是在函数y=3x+4中,x是变量,也是参数。那么什么这两个到底有什么区别和联系呢?我在网上搜了一下,发现很多说法,虽然大同小异,但是似乎只有下面这一段来自微软网站的比较高度抽象,而且意义涵盖深远。我摘抄过来,

  • = 赋值操作符(在其前后没有空白符)。 不要混淆 = 与 -eq,后者用来进行比较而非赋值。 同时也要注意 = 根据使用场景既可作赋值操作符,也可作比较操作符。 样例 4-2. 变量赋值 #!/bin/bash # 非引用形式变量 echo # 什么时候变量是非引用形式,即变量名前没有 '$' 符号的呢? # 当变量在被赋值而不是被引用时。 # 赋值 a=879 echo "The value o

  • 变量名是其所指向值的一个占位符(placeholder)。引用变量值的过程我们称之为变量替换(variable substitution)。 $ 接下来我们仔细区分一下变量名与变量值。如果变量名是 variable1, 那么 $variable1 就是对变量值的引用。[^1] bash$ variable1=23 bash$ echo variable1 variable1 bash$ echo