【问题标题】:Use of "instanceof" in Java [duplicate]在 Java 中使用“instanceof”[重复]
【发布时间】:2011-11-23 12:26:15
【问题描述】:

What is the 'instanceof' operator used for?

我了解到 Java 有 instanceof 运算符。能否详细说明一下它的用途以及它的优点是什么?

【问题讨论】:

  • 你看过this?
  • 这个 SO 链接应该会给你很多想法:stackoverflow.com/questions/496928/…
  • 如果我用谷歌搜索你的问题,我会得到 1170 万条结果。有没有什么您想知道的尚未详细讨论的内容?
  • 可能会重复,但是像这样的问题使 SO 成为所有技能水平的绝佳资源。我很高兴这是我搜索时的最佳结果。
  • 这里有一篇关于这个使用的好文章:javatpoint.com/downcasting-with-instanceof-operator

标签: java operators instanceof


【解决方案1】:

instanceof 是一个关键字,可用于测试对象是否属于指定类型。

例子:

public class MainClass {
    public static void main(String[] a) {

    String s = "Hello";
    int i = 0;
    String g;
    if (s instanceof java.lang.String) {
       // This is going to be printed
       System.out.println("s is a String");
    }
    if (i instanceof Integer) {
       // This is going to be printed as autoboxing will happen (int -> Integer)
       System.out.println("i is an Integer");
    }
    if (g instanceof java.lang.String) {
       // This case is not going to happen because g is not initialized and
       // therefore is null and instanceof returns false for null. 
       System.out.println("g is a String");
    } 
} 

这是我的source

【讨论】:

  • 使用 instanceof 运算符时,请记住 null 不是任何事物的实例。
  • 你为什么不用if?现在第二个和第三个条件没有被评估,因为第一个是true
  • @HummelingEngineeringBV 你说得对,我对 Tim 的评论反应有点太快了。我们确实想评估这些条件中的每一个。谢谢,已编辑。
【解决方案2】:

instanceof 用于检查对象是类的实例、子类的实例还是实现特定接口的类的实例。

Read more from the Oracle language definition here.

【讨论】:

    【解决方案3】:

    基本上,您检查对象是否是特定类的实例。 当你有一个超类或接口类型的对象的引用或参数并且需要知道实际对象是否有其他类型(通常更具体)时,你通常会使用它。

    例子:

    public void doSomething(Number param) {
      if( param instanceof Double) {
        System.out.println("param is a Double");
      }
      else if( param instanceof Integer) {
        System.out.println("param is an Integer");
      }
    
      if( param instanceof Comparable) {
        //subclasses of Number like Double etc. implement Comparable
        //other subclasses might not -> you could pass Number instances that don't implement that interface
        System.out.println("param is comparable"); 
      }
    }
    

    请注意,如果您必须经常使用该运算符,则通常暗示您的设计存在一些缺陷。因此,在设计良好的应用程序中,您应该尽可能少地使用该运算符(当然,该一般规则也有例外)。

    【讨论】:

    • Integer.class 格式真的合法吗?当我尝试在您的示例中使用它时,在 Eclipse 中,我得到Syntax error on token "class", Identifier expected。但是,将其切换为简单的 Integer 工作正常。
    • @etech 你是对的,我会解决的。我写这个答案已经有一段时间了;)
    • .equals() 方法中找到此方法的常见位置。 IntelliJ 生成使用 instanceof 的 equals 方法很常见
    • 只是想补充一下为什么使用此运算符表示设计缺陷。需要转换为具体类型的抽象没有提供足够的信息。它要么只是一些糟糕的抽象,要么是在错误的域中使用的抽象。您可以在此处通过示例查看详细说明:medium.com/@aerokhin/…
    【解决方案4】:

    instanceof 可用于确定对象的实际类型:

    class A { }  
    class C extends A { } 
    class D extends A { } 
    
    public static void testInstance(){
        A c = new C();
        A d = new D();
        Assert.assertTrue(c instanceof A && d instanceof A);
        Assert.assertTrue(c instanceof C && d instanceof D);
        Assert.assertFalse(c instanceof D);
        Assert.assertFalse(d instanceof C);
    }
    

    【讨论】:

    • 在某些情况下,您应该在设计中使用 instanceof,尤其是在开发 API 并引发误用异常时
    • 喜欢这个答案,但我正在创建一个词法分析器,我需要使用instanceof 来确定标记的类型(例如IdentifierLiteral 等...,从Token)。如果我不打算使用instanceof,那么我将拥有一个独特的Token 类,并且必须创建各种不必要的不​​同类型的字段来保存实际令牌的值。
    • 错过领先的答案,它采取一种情况并对整个关键字进行判断=\
    • @Hydro 您还可以为您的各种令牌引入一个专用的 \texttt{enum} 类。
    猜你喜欢
    • 1970-01-01
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 2019-08-29
    • 1970-01-01
    • 2016-03-18
    • 2016-04-02
    • 1970-01-01
    相关资源
    最近更新 更多