How can you determine if A is a subtype of B?

How can you determine if A is a subtype of B?
Java provides three main ways to check type compatibility. Functionally, they are similar but are used in different contexts. Here they are, ordered by performance:

instanceof. This binary operator is the fastest and most commonly used. If you have an instance of A and can specify B explicitly, this is the preferred choice. If A (or more precisely, the type of the variable holding an instance of A) and B are not in the same inheritance chain, the instance cannot possibly be a subtype of B, and the compilation will fail with an inconvertible types error.

Class::isInstance. This method takes an object of type A as a parameter. It should be chosen when you have an instance of A available, but B is not known at compile time. For instance, if you have variables A a and Class bClass, you can check with bClass.isInstance(a).

Class::isAssignableFrom. This method takes Class<A>. It’s the only option left if you don't have an instance of A. You would use it as bClass.isAssignableFrom(aClass).

There is also a fourth method – attempting to cast an instance of type A to type B. If the types are incompatible, this cast will throw a ClassCastException. However, this is universally considered a poor practice, as building program logic on the basis of exceptions is not advisable. The reasoning behind this is detailed in Effective Java Item 57.