CodeGym /Java 博客 /随机的 /Java instanceof 运算符
John Squirrels
第 41 级
San Francisco

Java instanceof 运算符

已在 随机的 群组中发布
你好!今天我们将讨论instanceof运算符,考虑其使用方式的示例,并探讨其工作原理的某些方面:) 您已经在 CodeGym 的早期级别遇到过此运算符。你还记得我们为什么需要它吗?如果没有,不用担心。让我们一起记住。需要instanceof运算符来检查X变量引用的对象是否基于某个Y类创建的。这听起来很简单。我们为什么回到这个话题?首先,因为现在您已经非常熟悉 Java 的继承机制和 OOP 的其他原则。instanceof运算符现在会更加清晰,我们将查看有关如何使用它的更高级示例我们走吧!instanceof 运算符如何工作 - 1您可能还记得,如果检查结果为真,则instanceof运算符返回,如果表达式为假,则返回假因此,它通常出现在各种条件表达式中(if…else)。让我们从一些更简单的例子开始:

public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof Integer);
   }
}
您认为控制台上会显示什么?好吧,这里很明显。:) x对象是一个整数,所以结果将为true。控制台输出: True 让我们尝试检查它是否是一个String

public class Main {

   public static void main(String[] args) {

       Integer x = new Integer(22);

       System.out.println(x instanceof String); // Error!
   }
}
我们得到一个错误。并注意:编译器在运行代码之前产生了错误!马上就看出IntegerString不能自动相互转换,也没有继承关系。因此,不会基于String创建 Integer 对象。这很方便并且有助于避免奇怪的运行时错误,因此编译器在这里帮助了我们 :) 现在让我们尝试考虑更困难的示例。由于我们提到了继承,让我们使用以下小类系统:

public class Animal {

}

public class Cat extends Animal {

}

public class MaineCoon extends Cat {

}
我们已经知道在检查一个对象是否是一个类的实例时instanceof 的行为 如何,但是如果我们考虑父子关系会发生什么?例如,您认为这些表达式会产生什么结果:

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究竟如何解释“基于类创建的对象”?' cat instanceof Animal ' 的计算结果为true,但我们肯定可以挑出该措辞的错误。为什么要基于Animal类创建Cat对象?不就是单独根据自己的类创建的吗?答案很简单,您可能已经想到了。记住创建对象时调用构造函数和初始化变量的顺序。我们已经在关于类构造函数的文章中介绍了这个主题。这是该课的一个例子:

public class Animal {

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

   public static int animalCount = 7700000;

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

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

public class Cat extends Animal {

   String tail = "Initial value of tail in the Cat class";

   static int catCount = 37;

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

   public static void main(String[] args) {
       Cat cat = new Cat("Brain", "Heart", "Tail");
   }
}
如果您在 IDE 中运行它,控制台输出将如下所示: Animal base class constructor is running Animal 类的变量是否已经初始化?静态变量animalCount当前值=7700000 Animal类brain当前值=Animal类brain初始值Animal类heart当前值=Animal类heart初始值已有Cat类变量初始化了吗?静态变量的当前值 catCount = 37 Animal 基类构造完成!brain 当前值 = Brain 当前值 heart = Heart cat 类构造函数已经启动(Animal 构造函数已经完成) 静态变量 catCount 当前值 = 37 tail 当前值 = Cat 类中 tail 的初始值 tail 当前值 =尾巴 现在你还记得吗?:) 基类的构造函数,如果有基类,在创建对象时总是先被调用。instanceof运算符在尝试确定A对象是否基于B类创建时受此原则指导。如果调用了基类的构造函数,那么就可以毫无疑问了。通过第二次检查,一切都变得更简单了:

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是一个短变量:它很容易适合一个变量,因为有足够的字节来容纳它(还记得娃娃的例子吗?)。 后代对象总是可以分配给祖先变量。现在,只需记住这一点,在后续课程中我们将分析它是如何工作的。那么我们的例子输出了什么?

Cat cat = new MaineCoon();
System.out.println(cat instanceof Cat);
System.out.println(cat instanceof MaineCoon);
instanceof 会检查什么?我们的Cat变量还是我们的MaineCoon对象?答案是这个问题其实很简单。你只需要再次阅读运算符的定义:需要instanceof运算符来检查X变量引用的对象是否基于某个Y类创建。instanceof运算符测试对象的来源,而不是变量类型因此,在此示例中,我们的程序将在两种情况下都显示为真:我们有一个MaineCoon对象。很明显,它是基于MaineCoon类创建的,但它是基于Cat创建的还有家长班!
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION