4

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

Electric Coffee
  • 11,733
  • 9
  • 70
  • 131
  • So, you want a generic method that locks it's type to one Object type. Why not just declare the type in the formal parameter? – christopher Mar 03 '13 at 19:00

3 Answers3

4

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)

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • 1
    This answer is correct, however... when the method is called without specifying a type, the type of `Object` is assumed - that's why you're not getting a compile error – Bohemian Mar 03 '13 at 19:05
  • but what I meant when I said it couldn't be called in that way, was syntactically, I kinda figured that there possibly was a way to do it... I just didn't know the correct syntax... so in a sense I was right, it isn't possible to do it with c# style syntax... – Electric Coffee Mar 03 '13 at 22:16
2

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")
Eyal Schneider
  • 22,166
  • 5
  • 47
  • 78
1

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.

newacct
  • 119,665
  • 29
  • 163
  • 224