Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to restrict that subclass cannot be generic?

Compile time error: The generic class may not subclass java.lang.Throwable

public class TestGenericClass<E> extends Exception {

/*Above line will give compile error, the generic class TestGenericClass<E> may 
  not subclass java.lang.Throwable*/

    public TestGenericClass(String msg) {
        super(msg);
    }
}

Above compile time error is for the reason given in § jls-8.1.2 as below, and explained in this question:

It is a compile-time error if a generic class is a direct or indirect subclass of Throwable(§11.1.1).

This restriction is needed since the catch mechanism of the Java Virtual Machine works only with non-generic classes.

Question:

  • How it is restricted that subclass of java.lang.Throwable will not be generic class?

  • Or more generic question will be, how to restrict that subclasses of any class cannot be generic?

like image 650
Vishrant Avatar asked May 03 '14 21:05

Vishrant


People also ask

How can we restrict generic to a subclass of particular class?

Whenever you want to restrict the type parameter to subtypes of a particular class you can use the bounded type parameter. If you just specify a type (class) as bounded parameter, only sub types of that particular class are accepted by the current generic class.

How can you prevent a class from being subclassed?

You can prevent a class from being subclassed by using the final keyword in the class's declaration. Similarly, you can prevent a method from being overridden by subclasses by declaring it as a final method. An abstract class can only be subclassed; it cannot be instantiated.

What are the restrictions on generics?

Cannot Use Casts or instanceof With Parameterized Types. Cannot Create Arrays of Parameterized Types. Cannot Create, Catch, or Throw Objects of Parameterized Types. Cannot Overload a Method Where the Formal Parameter Types of Each Overload Erase to the Same Raw Type.

Can a generic class be subclass of non generic?

A generic class can extend a non-generic class.


1 Answers

How it is restricted that subclass of java.lang.Throwable will not be generic class?

Here's how OpenJDK compiler performs the check:

import com.sun.tools.javac.code.Symbol.*;   

private void attribClassBody(Env<AttrContext> env, ClassSymbol c) {
    ....

    // Check that a generic class doesn't extend Throwable
    if (!c.type.allparams().isEmpty() && types.isSubtype(c.type, syms.throwableType))
        log.error(tree.extending.pos(), "generic.throwable");

As you can see forbidden type is kind of harcoded, so you can't use the same technique for your custom class without compiler code customization.

Full source code

like image 156
Jk1 Avatar answered Sep 20 '22 16:09

Jk1