JavaRush /Java 博客 /Random-ZH /Java 中的 Instanceof 运算符

Java 中的 Instanceof 运算符

已在 Random-ZH 群组中发布
你好!今天我们将讨论instanceof运算符,看一下它的使用示例,并讨论一些与其操作相关的要点:) 在JavaRush的早期阶段,您已经遇到过这个运算符。你还记得为什么需要它吗?如果没有,也没关系,我们一起记住。需要使用instanceof运算符来检查变量X引用的对象是否是从某个类Y创建的。听起来很简单。为什么我们又回到这个话题呢?首先,因为现在你已经熟悉了Java中的继承机制和其他OOP原理。instanceof的主题将会更加清晰,我们将研究更高级的用例。去!您可能还记得,如果测试为真,则Instanceof 运算符如何工作 - 1instanceof 运算符返回true ;如果结果为false ,则返回 false。因此,它最常见于各种类型的测试条件 ( if…else)。让我们从更简单的例子开始:
public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof Integer);
   }
}
你认为控制台会输出什么?嗯,这很明显:) 该对象х是一个 Integer,所以结果将为true。控制台输出:true 让我们尝试检查它是否属于字符串:
public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof String);// error!
   }
}
我们收到一个错误。请注意:编译器甚至在代码执行之前就发出了它!他立即看到Integer和String不能自动相互转换,并且不具有继承关系。因此,不会从 String 创建 Integer 类对象。这很方便,并且有助于避免在程序执行期间出现奇怪的错误,因此编译器在这里帮助了我们:) 现在让我们尝试看看更复杂的示例。既然我们提到了继承,那么让我们使用这个小型类系统:
public class Animal {

}

public class Cat extends Animal {

}

public class MaineCoon extends Cat {

}
我们已经知道正常情况下检查一个对象是否属于某个类时instanceof的行为如何,但是如果我们在这里添加父子关系会发生什么? Instanceof 运算符如何工作 - 2 例如,您认为以下检查会产生什么结果:
public class Main {

   public static void main(String[] args) {

       Cat cat = new Cat();

       System.out.println(cat instanceof Animal);

       System.out.println(cat instanceof MaineCoon);

   }
}
输出:true false 需要回答的主要问题是,instanceof 究竟如何破译“基于类创建的对象”的概念?结果,我们得到了它Сat instanceof Animal == true,但人们可能会对这样的表述提出错误。为什么这个对象是Cat基于类创建的Animal?不是只是根据自己的类创建的吗?答案很简单,您可能已经想到了。记住创建对象时调用构造函数和初始化变量的顺序。我们已经在有关类构造函数的文章中讨论了这个主题。这是该讲座中的一个例子:
public class Animal {

   String brain = "The initial value of brain in the Animal class";
   String heart = "The initial value of heart in the Animal class";

   public static int animalCount = 7700000;

   public Animal(String brain, String heart) {
       System.out.println("The constructor of the Animal base class is being executed");
       System.out.println("Have the variables of the Animal class already been initialized?");
       System.out.println("The current value of the static variable animalCount = " + animalCount);
       System.out.println("Current value of brain in class Animal = " + this.brain);
       System.out.println("Current value of heart in class Animal = " + this.heart);

       this.brain = brain;
       this.heart = heart;
       System.out.println("Animal base class constructor completed!");
       System.out.println("Current value of brain = " + this.brain);
       System.out.println("Current value of heart = " + this.heart);
   }
}

class Cat extends Animal {

   String tail = "The initial value of tail in the Cat class";

   static int catsCount = 37;

   public Cat(String brain, String heart, String tail) {
       super(brain, heart);
       System.out.println("The constructor of the Cat class has started (the Animal constructor has already been executed)");
       System.out.println("The current value of the static variable catsCount = " + catsCount);
       System.out.println("Current value tail = " + this.tail);
       this.tail = tail;
       System.out.println("Current value tail = " + this.tail);
   }

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
如果你在 IDE 中运行它,控制台输出将如下所示: The constructor of the base class Animal is running. Have the Variables of the Animal class have beeninitialized? 静态变量animalCount的当前值 = 7700000 Animal类中brain的当前值 = Animal类中brain的初始值 Animal类中heart的当前值 = Animal类中heart的初始值 Animal类基类的构造函数已经完成了它的工作!Brain 的当前值 = Brain Heart 的当前值 = Heart Cat 类的构造函数已经开始工作(Animal 构造函数已经执行完毕) 静态变量 catsCount 的当前值 = 37 tail 的当前值 = 中 tail 的初始值Cat 类 tail 当前值 = Tail 现在你还记得吗?:) 创建任何对象时,始终首先调用基类构造函数(如果有)。Instanceof 在尝试确定对象是否是А从类创建时遵循此原则Б。如果基类的构造函数被调用,那么就没有疑问了。通过第二次检查,一切都变得更简单:
System.out.println(cat instanceof MaineCoon);
MaineCoon创建时没有调用 构造函数Cat,这是合乎逻辑的。毕竟,MaineCoon他是后人Cat,不是祖先。但Cat它不是一个模板。好吧,这看起来很清楚。如果我们这样做会发生什么:
public class Main {

   public static void main(String[] args) {

       Cat cat = new MaineCoon();

       System.out.println(cat instanceof Cat);
       System.out.println(cat instanceof MaineCoon);


   }
}
嗯...这更复杂。让我们试着推理一下。我们有一个类型的变量Cat,并且为它分配了一个类型的对象MaineCoon。顺便问一下,为什么这会起作用?是否有可能做到这一点?能。毕竟,任何缅因猫都是猫。如果不完全清楚,请记住原始类型扩展的示例:
public class Main {

   public static void main(String[] args) {

       long x = 1024;

   }
}
数字1024:它很容易适合long变量,因为字节数足够了(还记得嵌套娃娃的例子吗?)。子对象始终可以分配给祖先变量。现在记住这一点,在接下来的讲座中我们将进一步分析这个过程。那么我们的例子会产生什么结果呢?
Cat cat = new MaineCoon();
System.out.println(cat instanceof Cat);
System.out.println(cat instanceof MaineCoon);
instanceof 将检查什么:我们的类变量Cat还是我们的类对象MaineCoon?其实,这个问题的答案很简单。你只需要再次阅读我们的运算符的定义:需要instanceof运算符来检查变量引用的对象是否是X基于某个类创建的Yinstanceof 运算符检查对象的来源,而不是变量。 因此,在示例中,两次都会在控制台中显示true:我们有一个类型为 的对象MaineCoon。当然,它是基于类创建的MaineCoon,但也是基于父类创建的Cat
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION