有没有理由在Java中使用泛型?(Is there any reason to use generics in Java?)

编程入门 行业动态 更新时间:2024-10-24 17:24:46
没有理由在Java中使用泛型?(Is there any reason to use generics in Java?)

也许我忽略了这一点,但是来自C#背景,我看不出有任何理由使用Java的泛型......

在C#中,我有一个方法,它接受一个字符串并将其反序列化为一个对象...

public static Deserialize<T>(string source) { // Use reflection to examine T and determine // which properties I should be reading from // the string. Create an instance of T, // populate the properties and return it }

我可以调用如下: x.Deserialize<AnyClass>("String representation of AnyClass");

类型擦除似乎使Java无法实现这一点?

我的下一个最常见的泛型用法是存储事物列表,但由于我不能做List<int>并且必须使用List<Integer> ,所以当我可以使用int[]时,它似乎毫无意义的开销装箱/拆箱。

所以...是仿制药唯一真正用于做的事情

List<MyClass> MyClassList = new List<MyClass>

并获得一些类型的编译时类型检查? 如果是这样的话,那似乎是多余的,因为变量名称清楚地说明了类型应该是什么(至少只要我使用合理的命名约定)。

我情不自禁地觉得我错过了一些东西......

Perhaps I'm missing the point but coming from a C# background, I can't see any reason to use Java's generics...

In C# I've got a method which takes a string and deserializes it into an object...

public static Deserialize<T>(string source) { // Use reflection to examine T and determine // which properties I should be reading from // the string. Create an instance of T, // populate the properties and return it }

which I can call as follows: x.Deserialize<AnyClass>("String representation of AnyClass");

Type erasure seems to make this impossible in Java?

My next most common usage of generics is storing things lists but since I can't do List<int> and have to box to use List<Integer>, it seems like pointless overhead boxing/unboxing when I could just use int[].

So... Is the only real use for generics to do things like

List<MyClass> MyClassList = new List<MyClass>

and get some type compile-time type checking? If so, it seems pretty redundant given that the variable name makes it clear what the type should be (at least as long as I'm using sensible naming conventions).

I can't help but feel I'm missing something...

最满意答案

好吧,如果你不使用泛型,你每次都可以进行投射。 你必须:

// if raw List MyClass c = (MyClass) myClassList.get(0); // if List<MyClass> MyClass c = myClassList.get(0);

例如。

是的,泛型在运行时被删除,是的,它们只是在编译时强制执行类型安全; 但是在使用边界时仍然存在运行时类型擦除。 例:

public <E extends RuntimeException> E get(final Class<E> c, final Throwable t) { try { return (E) getHandle(c).invokeExact(t); } catch (Error | RuntimeException e) { throw e; } catch (Throwable oops) { final RuntimeException exception = new IllegalStateException(oops); exception.addSuppressed(t); throw exception; } }

这里的E有一个运行时类型擦除; 它extends RuntimeException 。 因此, RuntimeException为RuntimeException ,而不是Object 。

有关运行时类型擦除的另一个有趣示例,请参阅Collections.max()的javadoc (提示:为什么它定义T extends Object & Comparable<? super T>而不是T extends Comparable<? super T> ?)

Well, if you don't use generics, you get to cast each time. You would have to:

// if raw List MyClass c = (MyClass) myClassList.get(0); // if List<MyClass> MyClass c = myClassList.get(0);

for instance.

Yes, generics are erased at runtime, yes, they are here to enforce type safety at compile time only; however there is still runtime type erasure when you use bounds. Example:

public <E extends RuntimeException> E get(final Class<E> c, final Throwable t) { try { return (E) getHandle(c).invokeExact(t); } catch (Error | RuntimeException e) { throw e; } catch (Throwable oops) { final RuntimeException exception = new IllegalStateException(oops); exception.addSuppressed(t); throw exception; } }

The E here has a runtime type erasure; it extends RuntimeException. Therefore the cast is to RuntimeException, not Object.

See the javadoc of Collections.max() for another interesting example of runtime type erasure (hint: why does it define T extends Object & Comparable<? super T> instead of T extends Comparable<? super T>?)

更多推荐

本文发布于:2023-08-04 02:54:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1405879.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:没有理由   Java   generics   reason

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!