简体   繁体   中英

how do I make a generic method lock its type in java?

what I mean about that is that in C# for example I can write a generic method like this:

public static void Concatenate<T> (T arg1, T arg2) 
{
    Console.WriteLine(arg1.ToString() + arg2.ToString());
}

and then if I call the method in these different ways:

Concatenate("one", "two"); // will work just fine, outputs "onetwo"
Concatenate(1, 2); // will also work great, outputs 12
Concatenate("one", 2) // will give a compiler error

alternately I could call the method like this: Concatenate<string>("one", "two"); and be extra sure only strings get in...

now if I try the exact same thing in Java

public static <T> void concatenate(T arg1, T arg2) {
    System.out.println(arg1.toString() + arg2.toString());
}

and call the method in the exact same way as in the c# example:

concatenate("one", "two"); // will work just fine, outputs "onetwo"
concatenate(1, 2); // will also work great, outputs 12
concatenate("one", 2) // will work fine and outputs "one2"

as far as I know I can't call the method like concatenate<String>("One", "Two"); as that will give me an error

is there any way I can add that sort of type safety I found in c#?

so I don't risk being able to just put any type in on either spot and only get a warning...

a better example would be using variable arguments

in C# I'd do:

public static void QuickSort<T>(params T[] args) // same as (T... args) in java
{
    // code
}

and upon calling it I'd be sure only one kind of parameter got in by for example doing something like:

QuickSort<int>(5, 9, 7, 3, 2, 5, 4, 1);

whereas in java I'd be able to do this:

quickSort(5, "nine", 7, 3, "two", 5, 4, 1);

and get nothing but a warning from the IDE, whereas it'd give an error in c#

so my question is, is there any way I can "lock" the parameter type in java like I can in c#, a-la QuickSort<int>(args) rather than quickSort(args) ?

as far as I know I can't call the method like concatenate<String>("One", "Two") as that will give me an error

Actually, you can, only the syntax is a bit different:

public class Main {

    public static <T> void concatenate(T arg1, T arg2) {
        System.out.println(arg1.toString() + arg2.toString());
    }

    public static void main(String[] args) {
        Main.<String>concatenate("one", "two"); // will work just fine, outputs "onetwo"
        Main.<Integer>concatenate(1, 2); // will also work great, outputs 12
        Main.<String>concatenate("one", 2); // will fail at compile time
    }
}

If concatenate() were a non- static method, the syntax would be obj.<String>concatenate(...) .

As to your second example:

public class Main {

    public static <T> void quickSort(T... args) {
    }

    public static void main(String[] args) {
        quickSort(5, "nine", 7, 3, "two", 5, 4, 1);                // warning
        Main.<Integer>quickSort(5, "nine", 7, 3, "two", 5, 4, 1);  // error
    }
}

Here, Main.<Integer>quickSort(...) fails with the following error:

The parameterized method quickSort(Integer...) of type Main is not applicable for the arguments (Integer, String, Integer, Integer, String, Integer, Integer, Integer)

You can be explicit with the generic parameter, but the syntax is different than the one you tried:

For Instance methods:

instance.<String>concatenate("a","b")

For static methods:

MyClass.<String>concatenate("a","b")

There is no "type safety" in what you are asking. Concatenate("one", 2) is pefectly type-safe. There is no reason to disallow it from a type safety point of view. Generics is not for making arbitrary restrictions.

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