如何解释这个 Java 泛型类型定义?
How to interpret this Java generic type definition?
下面是 netty 4.0.24
框架中的一些代码片段。解释 B
类型参数有点混乱。
public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C extends Channel> implements Cloneable
{
...
}
我认为它基本上是一个具有 2 个参数 B 和 C 的 class。第一个参数 (B) 必须是扩展 class 本身(或子级)和第二个参数 (C) 必须扩展 Channel.
在其中思考有点奇怪,但是您可以拥有一个 class 和 运行 具有相同类型的对象。
排序答案:它的参数是它自己和一个通道。
"B" 似乎代表了 Subclassed AbstractBootstrap 本身。它认为(恕我直言)这是一个奇怪的声明,使子类出现在通用参数中。
请查看 eclipse 中具有子类型层次结构的子类,您可能会发现类似
的内容
class AnyClass extends AbstractBootstrap<AnyClass,AChannel>
所以在这个例子中我们在它的通用声明中重复"AnyClass"
这可能被解释为curiously recurring template pattern的一种形式。
在这种情况下,类型参数B
的主要目的是能够在抽象class中引用继承类型。例如,AbstractBootstrap
class 有一个方法
B channel(Class<? extends C> channelClass)
所以这里的 return 类型是 第一个类型参数给出的任何类型。查看 AbstractBoottrap
class 的已知实现,可以发现
class Bootstrap extends AbstractBootstrap<Bootstrap,Channel>
和
class ServerBootstrap extends AbstractBootstrap<ServerBootstrap,ServerChannel>
他们收到 "themself" 作为第一个类型参数。所以这些实现的channel
方法会return"the type itself".
此处显示了一个可能的使用场景(使用一些虚拟 classes 使其可编译并指出相关部分):
public class BootstrapExample
{
public static void main(String[] args)
{
// On a Bootstrap, calling the 'channel' method
// will return a Bootstrap
Bootstrap bootstrap = new Bootstrap();
Bootstrap resultBootstrap =
bootstrap.channel(null);
// On a ServerBootstrap, calling the 'channel' method
// will return a ServerBootstrap
ServerBootstrap serverBootstrap = new ServerBootstrap();
ServerBootstrap resultSeverBootstrap =
serverBootstrap.channel(null);
}
}
abstract class AbstractBootstrap<
B extends AbstractBootstrap<B, C>,
C extends Channel> implements Cloneable
{
public B channel(Class<? extends C> channelClass)
{
return null;
}
}
class Bootstrap extends AbstractBootstrap<Bootstrap,Channel> {}
class ServerBootstrap
extends AbstractBootstrap<ServerBootstrap,ServerChannel> {}
class Channel {}
class ServerChannel extends Channel {}
旁白:我一直提倡类型安全,但是一旦嵌套了这些类型参数,您最终可能会得到 class- 或暗示类型边界的方法声明可以很难手动检查。因此,只有当可读性和类型安全之间的权衡确实合理时,才应使用它们。
下面是 netty 4.0.24
框架中的一些代码片段。解释 B
类型参数有点混乱。
public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C extends Channel> implements Cloneable
{
...
}
我认为它基本上是一个具有 2 个参数 B 和 C 的 class。第一个参数 (B) 必须是扩展 class 本身(或子级)和第二个参数 (C) 必须扩展 Channel.
在其中思考有点奇怪,但是您可以拥有一个 class 和 运行 具有相同类型的对象。
排序答案:它的参数是它自己和一个通道。
"B" 似乎代表了 Subclassed AbstractBootstrap 本身。它认为(恕我直言)这是一个奇怪的声明,使子类出现在通用参数中。
请查看 eclipse 中具有子类型层次结构的子类,您可能会发现类似
的内容class AnyClass extends AbstractBootstrap<AnyClass,AChannel>
所以在这个例子中我们在它的通用声明中重复"AnyClass"
这可能被解释为curiously recurring template pattern的一种形式。
在这种情况下,类型参数B
的主要目的是能够在抽象class中引用继承类型。例如,AbstractBootstrap
class 有一个方法
B channel(Class<? extends C> channelClass)
所以这里的 return 类型是 第一个类型参数给出的任何类型。查看 AbstractBoottrap
class 的已知实现,可以发现
class Bootstrap extends AbstractBootstrap<Bootstrap,Channel>
和
class ServerBootstrap extends AbstractBootstrap<ServerBootstrap,ServerChannel>
他们收到 "themself" 作为第一个类型参数。所以这些实现的channel
方法会return"the type itself".
此处显示了一个可能的使用场景(使用一些虚拟 classes 使其可编译并指出相关部分):
public class BootstrapExample
{
public static void main(String[] args)
{
// On a Bootstrap, calling the 'channel' method
// will return a Bootstrap
Bootstrap bootstrap = new Bootstrap();
Bootstrap resultBootstrap =
bootstrap.channel(null);
// On a ServerBootstrap, calling the 'channel' method
// will return a ServerBootstrap
ServerBootstrap serverBootstrap = new ServerBootstrap();
ServerBootstrap resultSeverBootstrap =
serverBootstrap.channel(null);
}
}
abstract class AbstractBootstrap<
B extends AbstractBootstrap<B, C>,
C extends Channel> implements Cloneable
{
public B channel(Class<? extends C> channelClass)
{
return null;
}
}
class Bootstrap extends AbstractBootstrap<Bootstrap,Channel> {}
class ServerBootstrap
extends AbstractBootstrap<ServerBootstrap,ServerChannel> {}
class Channel {}
class ServerChannel extends Channel {}
旁白:我一直提倡类型安全,但是一旦嵌套了这些类型参数,您最终可能会得到 class- 或暗示类型边界的方法声明可以很难手动检查。因此,只有当可读性和类型安全之间的权衡确实合理时,才应使用它们。