9

Below is some code snippet from the netty 4.0.24 framework. It's kind of confusing to interpret the B type parameter.

public abstract class AbstractBootstrap<B extends AbstractBootstrap<B, C>, C extends Channel> implements Cloneable
{
 ...
}
smwikipedia
  • 61,609
  • 92
  • 309
  • 482

3 Answers3

4

This can possibly be interpreted as one form of the curiously recurring template pattern.

In this case, the main purpose of the type parameter B is to be able to refer to the inheriting type in the abstract class. For example, the AbstractBootstrap class has a method

B channel(Class<? extends C> channelClass)

So the return type here is whatever type was given as the first type argument. Looking at the known implementations of the AbstractBoottrap class, one finds

class Bootstrap extends AbstractBootstrap<Bootstrap,Channel>

and

class ServerBootstrap extends AbstractBootstrap<ServerBootstrap,ServerChannel>

They receive "themself" as the first type parameter. So the channel method of these implementations will return "the type itself".

A possible usage scenario is shown here (with some dummy classes to make it compileable and point out the relevant part) :

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 {}

An aside: I'm always advocating for type safety, but once these type parameters are nested, you may end up with class- or method declarations that imply type bounds that can hardly be checked manually. So they should only be used when the trade off between readability and type safety is really justified.

Marco13
  • 53,703
  • 9
  • 80
  • 159
  • Reading this through, it looks like I could have the class declaration `class ServerBootstrap extends AbstractBootstrap`, as `Bootstrap` validly extends `AbstractBootstrap` and references itself in its own declaration. Is this correct? – MirroredFate Feb 12 '15 at 00:13
  • @MirroredFate This would not work due to the `Channel` vs. `ServerChannel` type parameter. But in principle, it is possible to create "unintuitive" (or plainly wrong) parametrizations, like `class Dog extends Animal` in http://stackoverflow.com/q/25365589/3182664 – Marco13 Feb 12 '15 at 08:01
1

I think it is basically a class that have 2 parameters, B and C. The first parameter (B) must be something that extends the class itself (or a child) and the second parameter (C) must extends Channel.

It's a little strange to think in it, but you can have a class that run with objects of it same type.

Sort answer: Its parameters are itself and a channel.

PhoneixS
  • 10,574
  • 6
  • 57
  • 73
0

"B" seem to represent the Subclassed AbstractBootstrap itself. It think (imho ) this is a strange declaration to make appear the subclass in generic arguments .

Please look at subclass with the subtype hierarchy in eclipse, you may find something like

class AnyClass extends AbstractBootstrap<AnyClass,AChannel>

So in this example we repeat "AnyClass" in its generic declaration

pdem
  • 3,880
  • 1
  • 24
  • 38