有界的通用比较器,适用于基类和派生类。

huangapple go评论85阅读模式
英文:

bounded Generic Comparator for base and derived classes

问题

我试图理解如何为给定的类及其所有派生类构建一个通用的比较器。

public class Employee {
    String name;
    int id;
}

在我的主类中,我尝试了以下代码:

Comparator<T extends Employee> comp = Comparator.comparing(Employee::getName);

但是IDE给出了错误信息:

意外的边界
英文:

I am trying to understand how to build a generic Comparator for the a given class and all derived class.

public class Employee {
    String  name;
    int id;
}

In my main class, I tried this

Comparator&lt;T extends Employee&gt; comp = new Comparator.comparing(Employee::getName);

and the IDE gives me the error

Unexpected bound

答案1

得分: 1

Maurice Perry's answer mungkin benar dalam hal memungkinkan baris itu untuk dikompilasi, tetapi itu tidak sangat berguna setelahnya: Anda tidak dapat memanggil comp.compare dengan argumen lain selain literal null.

Comparator&lt;? extends Employee&gt; berarti bahwa komparator menerima subkelas yang spesifik, tetapi tidak diketahui dari Employee: karena kompiler tidak tahu subkelas mana yang dimaksud, ia hanya akan memungkinkan Anda untuk melewatkan sesuatu yang pasti bisa dicasting dengan aman ke jenis yang tidak diketahui itu: yaitu, null.

Jika Anda menginginkan komparator yang lebih generik daripada Comparator&lt;Employee&gt;, Anda bisa menggunakan Comparator&lt;? super Employee&gt;, yang berarti komparator dengan aman dapat menerima sebuah instansi dari Employee (tetapi objek konkret mungkin dapat menerima sesuatu yang lebih umum).

Tetapi sebenarnya, Anda tidak ingin menggunakan wildcard jenis apa pun di sini. Wildcard hanya benar-benar berguna dalam parameter metode, agar metode dapat menerima objek yang lebih umum.

Anda seharusnya tidak menggunakannya dalam variabel atau tipe pengembalian (dll) karena Anda akan terjebak dengan tipe wildcard begitu Anda mendapatkannya - Anda tidak dapat (dengan aman) mencabut wildcard, jadi Anda terjebak dengan kerumitan ekstra dari ? extends atau ? super di mana-mana, yang sebenarnya hanya menyebabkan mata terasa tidak perlu.

Alasan mengapa Comparator&lt;T extends Employee&gt; tidak berfungsi adalah mencoba mendeklarasikan variabel tipe, T: Anda hanya bisa melakukannya pada kelas (atau antarmuka) atau pada tanda tangan metode. Tidak masuk akal untuk dapat mendeklarasikannya di dalam metode, karena Anda tidak dapat menggunakan jenis T tersebut secara berikutnya.

英文:

Maurice Perry's answer might be right in terms of allowing that line to compile, but it's not very useful afterwards: you can't invoke comp.compare with any other arguments than literal nulls.

Comparator&lt;? extends Employee&gt; means that the comparator accepts a specific, but unknown subclass of Employee: since the compiler does not know which subclass it is, it will only allow you to pass in something that it knows for sure can be safely cast to that unknown type: namely, null.

If you want a comparator which is somehow more generic than a Comparator&lt;Employee&gt;, you could use Comparator&lt;? super Employee&gt;, which means the comparator can safely accept an instance of Employee (but the concrete object may be able to safely accept a more general thing).


But really, you don't want to use any sort of wildcard here. Wildcards are only really useful in method parameters, in order to make a method able to accept more general objects.

You shouldn't use them in variables or return types (etc) because you're stuck with the wildcard type once you've got it - you can't (safely) cast away the wildcards, so you are stuck with the extra verbosity of the ? extends or ? super everywhere, which is really just unnecessary eye pain.


The reason why Comparator&lt;T extends Employee&gt; doesn't work is that is attempting to declare a type variable, T: you can only do that on a class (or interface) or on a method signature. It doesn't make sense to be able to declare it inside a method, since you can't subsequently use that type T.

答案2

得分: 0

尝试这样做:

Comparator<? extends Employee> comp = Comparator.comparing(Employee::getName);
英文:

Try this:

Comparator&lt;? extends Employee&gt; comp = Comparator.comparing(Employee::getName);

huangapple
  • 本文由 发表于 2023年7月24日 15:32:25
  • 转载请务必保留本文链接:https://go.coder-hub.com/76752272.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定