简体   繁体   中英

How to define a method that receives two arguments of type T, and S which extends T in java?

While studying Java Generics, I was wondering if it's possible to declare a method that receives two arguments, the first of which is of generic type T, and the second one is of generic type S, which extends (or is the same type as) T. So I started to experiment on this, and wrote the following method declaration:

public static <T, S extends T> void testMethod(T t, S s)
{
    System.out.println("We are inside testMethod.");
}

and then I called this method in two ways as follows:

java.lang.Integer num1 = new java.lang.Integer(0);
java.lang.Integer num2 = new java.lang.Integer(1);

testMethod(num1, num2);
testMethod(num1, new Object());

expecting the second call to cause a compile-time exception. But the program was compiled and run with no errors. Next, I changed the method testMethod declaration as follows:

public <T extends java.lang.Number, S extends T> void testMethod(T t, S s)

with the following calls:

testMethod(new Integer(0), new Double(1.1));
testMethod(new Integer(0), new Object());

The first call is error free, but the second one causes a compile-time error. It seems that as long as t and s are both subtypes of java.lang.Number , no error occurs, whether s is a subtype of t or not.

My question: How can we declare a method that receives two arguments, one of which is guaranteed to be a subtype of the other?

There are two problems:

  1. In terms of generics, any type is a subtype of itself. There's no way to declare S extends T such that S and T can't be the same type. Furthermore, even if it were possible, it wouldn't have much of an effect here, because any instance of S could also be passed as T .

  2. Type inference does its best to make the method compile. If S is not compatible with the type of the first argument, the compiler will infer the nearest common ancestor as T . You can avoid this issue by explicitly specifying T when you call the method:

     ThisClass.<Integer, Integer>testMethod(1, 2); // compiles ThisClass.<Integer, Integer>testMethod(1, 2.0); // does not compile 

The fact is that, ultimately, the method itself can't enforce the requirement that S is a subtype of (or even compatible with) t 's type. I don't think there's any way to work around that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM