被调用的泛型方法如何知道泛型返回的类型?

发布于 2024-08-25 17:15:41 字数 392 浏览 5 评论 0原文

我找不到 Java 的这个问题的重复项,尽管 C# 的问题有很多。

我有这样的方法:

public <T> T getSomething() {
 //
}

根据T的类型,我会有不同的返回。例如:

String a = getSomething();
int b = getSomething();

对于a,我的方法将返回一个特定的String。对于b,它将返回一个特定的int。等等。

看来这可以用C#中的typeof()来完成。我怎样才能用Java实现它?

I couldn't find a duplicate for this question for Java, although there are a lot of them for C#.

I have this method:

public <T> T getSomething() {
 //
}

According to the type of T, I will have a different return. For example:

String a = getSomething();
int b = getSomething();

For a, my method will return a specific String. For b, it will return a specific int. And so on.

It seems that this can be done with typeof() in C#. How can I achieve it in Java?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一梦等七年七年为一梦 2024-09-01 17:15:41

不幸的是,这对于 Java 来说是不可能的,因为它使用一种称为“类型擦除”的技术来允许泛型在不更改 JVM 的情况下工作。结果是,当调用该方法时,它所知道的只是对象,因此它永远无法找出预期返回的类型。

Unfortunately this is not possible with Java because it uses a technique called "type erasure" to allow generics to work without changing the JVM. The upshot is that when the method is called, all it knows about are Objects, so it can't ever find out what type it is expected to return.

如若梦似彩虹 2024-09-01 17:15:41

除非您在 getSomething 方法中有一些代码,否则您的示例将不起作用。如果我写

public <T> T getSomething(){ return null;}

它可以编译,但没有意义。但是,您通常会从上下文中获取 T:

public class Foo<T>{ 
  public T getSomething()... 
}
new Foo<String>().getSomething()...

大概您的实现中必须有一些类型感知的东西。

Your example doesn't work unless you have some code inside the getSomething method. If I write

public <T> T getSomething(){ return null;}

it compiles, but it's meaningless. However, you'd normally get your T from the context:

public class Foo<T>{ 
  public T getSomething()... 
}
new Foo<String>().getSomething()...

Presumably there'd have to be something in your implementation that's type aware.

海螺姑娘 2024-09-01 17:15:41

在 Java 中,更正常的写法是:

public <T> List<T> getSomeThings() {
    //
}

这样就可以了。

可能与您在 C# 中看到的直接等效的内容是这样的:

public <T> T getSomething(Class<? extends T> clazz) {
    //
}

但是将使用反射,这几乎肯定是一个坏主意。当然,您可以使用沼泽标准工厂来避免反射:

public <T> T getSomething(FactoryThing<? extends T> factory) {
    //
}

在某些情况下,推断返回类型很有用。例如,从 Java 序列化流中读取数据时,由于 1.5 之前的 API 设计,未检查的强制转换警告是无法合理避免的。我建议使用包私有方法来保持这一点。

In Java, it would be more normal to write something like:

public <T> List<T> getSomeThings() {
    //
}

That works just fine.

Possibly the direct equivalent of what you have seen in C# would go something like:

public <T> T getSomething(Class<? extends T> clazz) {
    //
}

But will use reflection, which will almost certainly be a bad idea. You can, of course, avoid reflection using a bog standard factory:

public <T> T getSomething(FactoryThing<? extends T> factory) {
    //
}

There are occasional cases where inferring the return type is useful. For instance, reading from a Java serialisation stream where due to pre-1.5 API design, unchecked cast warnings are not reasonably avoidable. I suggest keeping this tight with a package-private method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文