杰瑞科技汇

Java中not instanceof的使用场景与注意事项?

Of course! This is an excellent question that touches on a fundamental aspect of Java's type system.

Java中not instanceof的使用场景与注意事项?-图1
(图片来源网络,侵删)

The instanceof operator is used to check if an object is an instance of a specific class or interface. The "not instanceof" check is simply the logical negation of that.

There are two primary ways to express "not instanceof" in Java:

  1. Using the logical NOT operator () - The most common and recommended way.
  2. Using a method from the Objects utility class - A more modern, explicit, and sometimes safer approach.

The (Logical NOT) Operator

This is the most straightforward and widely used method. You place the operator before the instanceof check.

Syntax

if (!(object instanceof SomeType)) {
    // Code to execute if the object is NOT an instance of SomeType
}

Example

Let's imagine you have a method that processes different types of Payment but needs to reject CreditCard payments for a specific reason.

Java中not instanceof的使用场景与注意事项?-图2
(图片来源网络,侵删)
class Payment {}
class CreditCard extends Payment {}
class PayPal extends Payment {}
public class PaymentProcessor {
    public void processPayment(Payment payment) {
        // Check if the payment is NOT a CreditCard
        if (!(payment instanceof CreditCard)) {
            System.out.println("Processing payment (generic logic for non-credit cards)...");
            // ... generic processing logic
        } else {
            // It is a CreditCard
            System.out.println("Cannot process. Credit card payments are disabled for this transaction.");
            // ... specific logic for rejecting credit cards
        }
    }
    public static void main(String[] args) {
        PaymentProcessor processor = new PaymentProcessor();
        Payment paypalPayment = new PayPal();
        Payment creditCardPayment = new CreditCard();
        processor.processPayment(paypalPayment); // Will enter the 'if' block
        processor.processPayment(creditCardPayment); // Will enter the 'else' block
    }
}

Output:

Processing payment (generic logic for non-credit cards)...
Cannot process. Credit card payments are disabled for this transaction.

When to Use It

This is the standard, idiomatic way to perform a "not instanceof" check in Java. It's concise, readable, and understood by all Java developers.


Using Objects.isNotInstance() (Java 9+)

Since Java 9, the java.util.Objects class provides a utility method for this exact purpose. This approach can be more readable in some contexts and makes the intent explicit.

Syntax

if (Objects.isNotInstance(object, SomeType.class)) {
    // Code to execute if the object is NOT an instance of SomeType
}

Example

Using the same Payment classes as before:

Java中not instanceof的使用场景与注意事项?-图3
(图片来源网络,侵删)
import java.util.Objects;
// ... (Payment, CreditCard, PayPal classes are the same)
public class PaymentProcessor {
    public void processPayment(Payment payment) {
        // Using Objects.isNotInstance for clarity
        if (Objects.isNotInstance(payment, CreditCard.class)) {
            System.out.println("Processing payment (generic logic for non-credit cards)...");
            // ... generic processing logic
        } else {
            // It is a CreditCard
            System.out.println("Cannot process. Credit card payments are disabled for this transaction.");
            // ... specific logic for rejecting credit cards
        }
    }
    public static void main(String[] args) {
        // ... main method is the same
    }
}

The output is identical to the first example.

When to Use It

  • Readability: Some developers find Objects.isNotInstance(object, Type.class) more descriptive than !(object instanceof Type). It clearly states the intent of "checking for non-instance."
  • Explicitness: It removes the need for parentheses, which can sometimes improve code formatting.
  • Safety: The Objects method explicitly requires a Class object (SomeType.class), which can prevent some subtle compilation errors that might occur with a raw instanceof check in complex generic scenarios.

Important Consideration: The Pattern Matching instanceof (Java 16+)

Since Java 16, you can use pattern matching with instanceof to simultaneously check the type and cast the variable in one step. The "not" version of this is simply the negation of the entire pattern-matching expression.

Syntax

if (!(payment instanceof CreditCard cc)) {
    // payment is NOT a CreditCard
    // 'cc' is NOT available here
} else {
    // payment IS a CreditCard
    // 'cc' is a variable of type CreditCard, holding the cast value of 'payment'
    System.out.println("Rejecting credit card: " + cc.getCardNumber());
}

Example

// ... (Payment, CreditCard, PayPal classes are the same)
public class PaymentProcessor {
    public void processPayment(Payment payment) {
        if (!(payment instanceof CreditCard cc)) {
            System.out.println("Processing payment (generic logic for non-credit cards)...");
        } else {
            // 'cc' is automatically cast and available here
            System.out.println("Cannot process. Rejecting credit card: " + cc.getCardNumber());
        }
    }
    public static void main(String[] args) {
        // ... main method is the same
    }
}

Note: For this to compile, CreditCard must have a getCardNumber() method.

Summary and Recommendation

Method Syntax Pros Cons
Logical NOT () if (!(obj instanceof Type)) - Idiomatic, standard Java.
- Concise.
- Works in all Java versions.
- Requires parentheses.
- Intent is slightly less explicit than Objects.isNotInstance.
Objects.isNotInstance() if (Objects.isNotInstance(obj, Type.class)) - Very explicit and readable intent.
- No need for parentheses.
- Safer with generics.
- Requires Java 9+.
- Slightly more verbose.
Pattern Matching if (!(obj instanceof Type var)) - Combines type check and cast.
- Reduces boilerplate code.
- Requires Java 16+.
- The negates the entire pattern, not just the type.

Recommendation:

  • For general-purpose code in any Java version, !(object instanceof Type) is the standard and perfectly acceptable choice.
  • If you are using Java 9 or later and want to make your code's intent exceptionally clear, Objects.isNotInstance(object, Type.class) is an excellent alternative.
  • If you are using Java 16 or later and need to perform a type check and a cast, use the pattern matching instanceof. The "not" version is simply !(... instanceof Type var).
分享:
扫描分享到社交APP
上一篇
下一篇