Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to interpret this Java generic type definition?

Tags:

java

netty

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
{
 ...
}
like image 733
smwikipedia Avatar asked Feb 10 '15 08:02

smwikipedia


People also ask

How do you read Java generics?

“Java Generics are a language feature that allows for definition and use of generic types and methods.” Generic types are instantiated to form parameterized types by providing actual type arguments that replace the formal type parameters. A class like LinkedList<E> is a generic type, that has a type parameter E .

How do you define a generic in Java?

The syntax for a generic method includes a list of type parameters, inside angle brackets, which appears before the method's return type. For static generic methods, the type parameter section must appear before the method's return type.

How do you declare a generic type in a class explain?

The declaration of a generic class is almost the same as that of a non-generic class except the class name is followed by a type parameter section. The type parameter section of a generic class can have one or more type parameters separated by commas.


2 Answers

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.

like image 172
Marco13 Avatar answered Oct 17 '22 06:10

Marco13


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.

like image 20
PhoneixS Avatar answered Oct 17 '22 07:10

PhoneixS