【问题标题】:Why int and Integer in parent-child relationship always print int in java?java - 为什么父子关系中的int和Integer总是在java中打印int?
【发布时间】:2018-06-20 02:58:20
【问题描述】:

我试图在下面的代码 sn-p 中打印整数值,但每次它都会打印 int 块。为什么会这样?

class A {
    void methodOne(int i) {
        System.out.println("int " + i);
    }
}

class B extends A {
    void methodOne(Integer i) {
        System.out.println("Integer " + i);
    }
}

public class Solution {
    public static void main(String[] args) {
        A a = new B();
        a.methodOne(10);
        a.methodOne(new Integer(10));
        B b = new B();
        b.methodOne(20);
    }
}

输出:

int 10
int 10
int 20

为什么它总是打印 int,而不是 integer?

【问题讨论】:

  • 这与 Swing 没有任何关系!不要添加不相关的标签。
  • 你试过b.methodOne(new Integer(20));吗?

标签: java java-8 integer


【解决方案1】:

您的问题有一个简单的答案。我将证明每种情况的输出,然后是解决方案。在此之前,关于您的代码 sn-p 的一些说明:

  • 作为B 类扩展A,并具有相同的方法methodOne 和不同类型的参数(Integer),它有两个重载版本的方法methodOne
  • A a = new B(); 这里,aBA 类型的实例化。

理由:

  1. a.methodOne(10):参数10的类型为int。因此,A 类的 void methodOne(int i) 被调用。
  2. a.methodOne(new Integer(10)):参数new Integer(10) 的类型是Integer,但子类B 中的方法methodOne(Integer i)a 不可见。因此new Integer(10) 被拆箱为int 10 并再次调用A 类的void methodOne(int i)
  3. b.methodOne(20):由于bB 的实例化,它具有方法methodOne 的两个版本。但是参数10 的类型是int,因此再次调用了A(其父类)类的void methodOne(int i)

解决办法:

B b = new B();
b.methodOne(new Integer(20));

这里,参数20的类型是Integer。所以B类的void methodOne(Integer i)被调用了。

这里有一个小实验,可以帮助你理解子类的方法在父类中的不可见性。在 B 类中放置一个虚拟方法并尝试使用类型为 A实例化类型为 B 的对象进行访问。以下是修改后的代码。

// Place this method in Class B
void test(){

}

//In the main method
A a = new B();
// a.test();  
// The test method will not be available in class `A`, though the instantation of `a` is of type `B`.

【讨论】:

    【解决方案2】:

    该行为与自动装箱和自动拆箱有关。由于这两种情况的通用行,请注意此示例与方法覆盖相关。

    A a = new B();
    a.methodOne(10); /* line 1 */
    a.methodOne(new Integer(10)); /* line 2 */
    B b = new B();
    b.methodOne(20); /* line 3 */
    b.methodOne(new Integer(20)); /* line 4 */
    

    场景 1:

    class A {
        void methodOne(Integer i) {
            System.out.println("Integer " + i);
        }
    }
    
    class B extends A {
        void methodOne(int i) {
            System.out.println("int " + i);
        }
    }
    

    输出

    Integer 10 /* line 1, [AutoBoxing] */
    Integer 10 /* line 2 */
    int 20     /* line 3, B has method(int) */
    Integer 20 /* line 4, B has method(Integer) */
    

    场景 2

    class A {
        void methodOne(int i) {
            System.out.println("int " + i);
        }
    }
    
    class B extends A {
        void methodOne(Integer i) {
            System.out.println("Integer " + i);
        } 
    }
    

    输出

    int 10     /* line 1 */
    int 10     /* line 2, [auto unboxing] */
    int 20     /* line 3 */
    Integer 20 /* line 4 */
    

    【讨论】:

      【解决方案3】:

      B 类扩展了 A 类,因此它还包含 A 类的方法。

      这就是为什么,当你调用methodOne()时,你会从B类中调用A类的methodOne(),因为A类是主类,B类是A类的子类。所以,首先采用 A 类,这就是它从 A 类的 methodOne() 打印“int”而不是从 B 类的 methodOne() 打印“Integer”的原因。

      解决方案:- 将 Class B 的 methodOne() 重命名为 'methodTwo()' 或任何其他名称,然后在要打印 'Integer' 的位置调用该方法。

      【讨论】:

      • 改变方法 name 显然不是解决方案。 OP询问这种行为的原因。即使不更改方法名称,您也可以获得所需的答案Integer 10
      • 原因是A类是主类,B类是子类。所以,A类在B类之前被引用。
      • 我不知道您对 e 有什么问题,以及为什么您在我正确回答问题时投了反对票,也描述了原因。
      【解决方案4】:
      class A {
          void methodOne(Integer i) {
              System.out.println("Integer " + i);
          }
      }
      
      class B extends A {
          void methodOne(int i) {
              System.out.println("int " + i);
          }
      }
      
      public class Solution {
          public static void main(String[] args) {
              A a = new B();
              a.methodOne(10);
              a.methodOne(10);
              B b = new B();
              b.methodOne(20);
          }
      }
      

      【讨论】:

      • 这将打印 Integer 10 Integer 10 int 20
      • 当然。那么这如何回答这个问题呢? OP 想知道为什么会发生某些事情。一堆没有解释的代码不会真正帮助任何人。
      • 由于自动拆箱。结果将在 where -> if I put Integer I in class B and int i in class A, 因为类 A 将包含 int 作为参数,从而导致 Integer 被拆箱,并且方法被调用.由于扩展到类 A,B 类将包含两个 methodOne,而 A 类又会自动调用 A 类的 methodOne,从而打印 int i。因此,我将在 A 类和 B 类之间交换参数。
      猜你喜欢
      • 2010-09-05
      • 2018-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多