Finite class compiler error instance

The following code compiles fine:

interface Flyer{ } class Bat { } public class App { public static void main(String[] args) { Bat b = new Bat(); if(b instanceof Flyer) System.out.println("b is a Bird"); } } 

If we create the Bat final class, the code does not compile:

 final class Bat { } 

If the last class implements Flyer , it compiles fine:

 final class Bat implements Flyer { } 

Anyone want to explain the logic behind this?

+5
source share
3 answers

When you make the Bat final class, you say that this class cannot be subclassed. Since Bat does not implement the Flyer interface, the compiler can determine that b instanceof Flyer never be true and causes an error.

This is indicated in the JLS section 15.20.2 :

If the listing (ยง15.16) of the RelationalExpression for ReferenceType is rejected as a compile-time error, then the instanceof relational expression also throws a compile-time error. In such a situation, the result of the instanceof expression can never be true.

In addition, from section 15.16 on expression expressions:

This is a compile-time error if the instance type of the compilation type can never be applied to the type specified by the casting operator in accordance with casting conversion rules (ยง5.5).

In this case, Bat never be applied to Flyer : it does not implement it, and final guarantees that there cannot be subclasses that implement it.


As you learned, corrections:

  • Make a Bat implementation of Flyer : in this case, the instanceof operator will always return true .
  • Remove the final identifier, implying that there may be subclasses of the Bat implementation of the Flyer .
+6
source

Well, if Bat is the final class and does not implement Flyer , it cannot have any subclass that Flyer implements, so instanceof never return true. In such cases, the compiler does not allow this expression (i.e. (x instanceof Y) is only allowed if x likely to contain a reference to an instance that implements or extends Y ).

In your second Bat snippet, Flyer is already implemented, so b instanceof Flyer will always return true , regardless of whether Bat final or not.

+4
source

In addition to the JT @Tunaki link, this is also explicitly explained in https://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.5.1 , quoting the corresponding rule:

If S is a final class (ยง8.1.1), then S must implement T, or a compile-time error occurs.

Of An instanceof checks these rules to bring a reference type.

+4
source

Source: https://habr.com/ru/post/1239729/


All Articles