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

Java方法重载并选择最特定的类型

盛浩阔
2023-03-14
问题内容

示例代码为:

    public class OverloadingTest {

       public static void test(Object obj){
           System.out.println("Object called");
       }

       public static void test(String obj){
           System.out.println("String called");
       }

       public static void main(String[] args){
           test(null);
           System.out.println("10%2==0 is "+(10%2==0));
           test((10%2==0)?null:new Object());
           test((10%2==0)?null:null);
   }

输出为:

String called 10%2==0 is true Object called String called

的第一个调用会test(null)调用带有String参数的方法,根据可以理解The Java Language Specification

1)谁能解释我test()在先前的调用中是基于什么来调用的?

2)再说一次,说一个if条件:

    if(10%2==0){
        test(null);
    }
    else
    {
        test(new Object());
    }

它总是使用Stringarguments 调用方法。

编译器在编译时会计算表达式(10%2)吗?我想知道表达式是在编译时还是在运行时计算的。谢谢。


问题答案:

Java使用早期绑定。在编译时选择最具体的方法。根据参数数量和参数类型选择最具体的方法。在这种情况下,参数数量无关紧要。这给我们留下了参数的类型。

参数有什么类型?两个参数都是使用三元条件运算符的表达式。问题简化为:条件三元运算符返回哪种类型?类型是在编译时计算的。

给出两个表达式:

(10%2==0)? null : new Object(); // A
(10%2==0)? null : null; // B

这里列出类型评估的规则。在B很容易,这两个方面是完全一样的:null将返回(无论何种类型,可能是)(JLS:“如果第二个和第三个操作数具有相同的类型(可能是空型),然后就是类型条件表达式。”)。在A第二项是从一个特定的类。因为这更具体,并且null可以替换类Object的对象,所以整个表达式的类型为Object(JLS:“如果第二个和第三个操作数之一为空类型,而另一个html" target="_blank">操作符的类型为引用类型,则条件表达式的类型就是该引用类型。”)。

在对表达式的类型求值之后,方法选择就如预期的那样。

给出的示例if有所不同:你使用两种不同类型的对象调用方法。三元条件运算符总是在编译时被评估为适合两种条件的一种类型。



 类似资料:
  • 问题内容: 我试图弄清楚Java如何选择执行哪种方法: 我在这里学到的是 方法签名是根据编译时数据类型确定的 实际调用的方法取决于调用该方法的对象的动态类型。 基于此,前两个调用的结果符合预期。但是,我不理解示例3和4的结果。 它似乎是在Java语言规范中指定的,但我不理解。 问题答案: 但是,我不理解示例3和4的结果。 好吧,让我们单独看一下。 例子3 重要的部分是表达式和的 编译时 类型。 仅

  • 问题内容: 给出以下代码: 输出(意外)如下: 问题出在第一行,我希望与其他两行相同。此外,我发誓直到最近,编译器仍会为我的普通调用给出模糊的调用警告。但是,使用Java 5和6进行编译和测试会产生相同的结果。 这对我来说是一个重要的问题,因为我有很多代码都使用这种模式,即使用不同类型的重载“默认”参数来选择返回类型并推断所需的转换/解析。谁能解释这是怎么回事? 问题答案: Java始终以相同的方

  • 问题内容: 我正在尝试以下代码: 打印三遍。我希望方法选择要考虑实际的(而不是声明的)参数类型。我想念什么吗?是否有修改此代码,以便它会打印的方式, 问题答案: 我希望方法选择要考虑实际的(而不是声明的)参数类型。我想念什么吗? 是。您的期望是错误的。在Java中,动态方法分派仅发生在调用方法的对象上,而不发生在重载方法的参数类型上。 引用Java语言规范: 调用方法时(第15.12节),实际参数

  • 我有这个: 我想选择类为col-md-4,6,8,12的排班的孩子。有没有什么好办法一次全选? 可以有多个行DIV,我将使用wrapAll将每个行DIV的子级包装到其他DIV中。所以如果我使用wrapAll,它只是将其他行div的所有内容转移到第一个行div。如果我将选择器查询放在循环内部,它只是继续包装子项乘以行divs的数量。我不想让这种事发生。 你们听懂了吗?

  • 根据这一https://docs.oracle.com/javase/specs/jls/se18/html/jls-15.html#jls-15.12.2.5,Java编译器将尝试选择最具体的方法来调用时,有多个适用的和可访问的,直觉是更具体的方法可以取代较不具体的,但不是相反。 所以我有点惊讶,当我们在通用包装器中包装模糊调用时,这不会起作用,如下所示: 所以我们可以看到,只要调用就可以让它按

  • 例如,'workspace'目录存在于C://folder1/folder2/wokspace中,我希望允许FileChooser在C://处“启动”,并允许用户导航到'workspace'文件夹并接受它。FileChooser不应该允许接受Folder1或Folder2,但仍然允许通过Folder1和Folder2导航。