简体   繁体   English

如何使通用方法在java中锁定其类型?

[英]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: 我的意思是在C#例如我可以写一个像这样的通用方法:

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"); 或者我可以像这样调用方法: Concatenate<string>("one", "two"); and be extra sure only strings get in... 并且确保只有字符串进入......

now if I try the exact same thing in Java 现在如果我在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: 并以与c#示例完全相同的方式调用该方法:

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"); 据我所知,我不能像concatenate<String>("One", "Two");那样调用方法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#? 有什么方法可以添加我在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: 在C#我会这样做:

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: 而在java中,我可以这样做:

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# 除了来自IDE的警告之外什么都得不到,而它在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) ? 所以我的问题是,有没有什么办法可以像在c#,a-la QuickSort<int>(args)而不是quickSort(args)那样“锁定”java中的参数类型?

as far as I know I can't call the method like concatenate<String>("One", "Two") as that will give me an error 据我所知,我不能像concatenate<String>("One", "Two")那样调用方法concatenate<String>("One", "Two")因为这会给我一个错误

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(...) . 如果concatenate()是非static方法,则语法为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: 这里, Main.<Integer>quickSort(...)失败,出现以下错误:

The parameterized method quickSort(Integer...) of type Main is not applicable for the arguments (Integer, String, Integer, Integer, String, Integer, Integer, Integer) Main类型的参数化方法quickSort(Integer ...)不适用于参数(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. Concatenate("one", 2)是完全类型安全的。 There is no reason to disallow it from a type safety point of view. 从类型安全的角度来看,没有理由不允许它。 Generics is not for making arbitrary restrictions. 泛型不是用于任意限制。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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