Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

method signature in inheritance

In the code below

class A {
    public void v(int... vals) {
        System.out.println("Super");
    }
}

class B extends A {
    @Override
    public void v(int[] vals) {
        System.out.println("Sub");
    }
}

Then I can call new B().v(1, 2, 3);//print Sub rather than Super which is ridiculous but does work well. If I change B to

class B {
    public void v(int[] vals) {
        System.out.println("Not extending A");
    }
}

the call to new B().v(1, 2, 3); will be invalid. You have to call it as new B().v(new int[]{1, 2, 3});, why?

like image 409
charles_ma Avatar asked Jul 31 '13 20:07

charles_ma


People also ask

What is a method signature?

The method signature in java is defined as the structure of the method that is designed by the programmer. The method signature is the combination of the method name and the parameter list. The method signature depicts the behavior of the method i.e types of values of the method, return type of the method, etc.

What is the signature of a method example?

The signature of a method consists of the name of the method and the description (i.e., type, number, and position) of its parameters. Example: toUpperCase() println(String s)

What is signature in method overriding?

Having two or more methods with the same name and signature as method in the parent class is known as method overriding. Method overriding allows us to invoke functions from base class to derived class.

What is method signature in Java with example?

In Java, a method signature is part of the method declaration. It's the combination of the method name and the parameter list. The reason for the emphasis on just the method name and parameter list is because of overloading. It's the ability to write methods that have the same name but accept different parameters.


1 Answers

Under JDK 1.7, neither of your examples compiles, and I don't believe they should.

It's easy to see why the second version doesn't - when B doesn't extend A, there's no indication of varargs at all, so there's no reason why the compiler should possibly convert an argument list of three int arguments into a single int[]. The more interesting situation is where B does extend A.

The compiler finds a signature of v(int[] vals) which doesn't use varargs. There's nothing in the spec to say it should look up the inheritance chain to find whether one of the other declarations (there could be multiple ones) uses varargs. The fact that it appears to in your version of JDK 1.6 suggests that was a compiler bug which has since been fixed. (I've just reproduced the bug in JDK 1.6.0_39 as well.)

Basically, if you want to be able to invoke B.v() in a varargs-style syntax, B.v() should be declared using varargs. Of course, if you change it so that the compile-time type is A, that would work:

A a = new B();
a.v(1, 2, 3);

Or even (ick):

((A) new B()).v(1, 2, 3);

Note that if you compile with -Xlint you get a warning about B anyway:

Test.java:14: warning: v(int[]) in B overrides v(int...) in A; overriding method
 is missing '...'
    public void v(int[] vals) {
                ^
like image 73
Jon Skeet Avatar answered Oct 12 '22 06:10

Jon Skeet