Question

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)?

Was it helpful?

Solution

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)

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top