1、操作符“==”
用来比较两个操作元是否相等,这两个操作元既可以是基本类型,也可以是引用类型。
代码01:
/**
* Demo01.java
*
* Provider: CoderDream's Studio
*
* History
* Date(DD/MM/YYYY) Author Description
* ----------------------------------------------------------------------------
* Nov 13, 2007 CoderDream Created
*/
package com.coderdream.operator;
/**
* discription: 操作符“==”
*
* @author CoderDream
*
*/
public class Demo01 {
/**
* <pre>
* 操作符“==”用来比较两个操作元是否相等,这两个操作元既可以是基本类型,也可以是引用类型。
* </pre>
*/
public static void f1() {
int a1 = 1, a2 = 3;
boolean b1 = a1 == a2; // "=="的操作元为基本类型,b1变量值为false
System.out.println(b1);
String str1 = "Hello", str2 = "World";
boolean b2 = str1 == str2; // "=="的操作元为引用类型,b2变量值为false
System.out.println(b2);
}
/**
* <pre>
* 当操作符“==”两边都是引用类型时,这两个引用变量必须都引用同一个对象,结果才为true。
* </pre>
*/
public static void f2() {
Integer int1 = new Integer(1);
Integer int2 = new Integer(1);
Integer int3 = int1; // int3和int1引用同一个对象
int[] array1 = new int[1];
int[] array2 = new int[1];
int[] array3 = array1; // array3和array1引用同一个对象
System.out.println("int1==int2 is " + (int1 == int2));
System.out.println("int1==int3 is " + (int1 == int3));
System.out.println("array1==array2 is " + (array1 == array2));
System.out.println("array1==array3 is " + (array1 == array3));
}
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("-----------f1()-----------");
Demo01.f1();
System.out.println("-----------f2()-----------");
Demo01.f2();
}
}
输出结果:
-----------f1()-----------
false
false
-----------f2()-----------
int1==int2 is false
int1==int3 is true
array1==array2 is false
array1==array3 is true
2、操作符“==”与多态性
a、对于引用类型变量,Java编译器根据变量被显式声明的类型去编译。当“==”用于比较引用类型变量时,“==”两边的变量被显式声明的类型必须是同种类型或有继承关系,即位于继承树的同一个继承分支上,否则编译出错。
b、在运行时,Java 虚拟机将根据两边的引用变量实际引用的对象进行比较。
假设有4个类--Creature、Animal、Dog和Cat类,它们的继承关系如图所示:
代码02:
/**
* Demo02.java
*
* Provider: CoderDream's Studio
*
* History
* Date(DD/MM/YYYY) Author Description
* ----------------------------------------------------------------------------
* Nov 13, 2007 CoderDream Created
*/
package com.coderdream.operator;
/**
*
* <pre>
* 操作符“==”与多态性
* 1、对于引用类型变量,Java编译器根据变量被显式声明的类型去编译。当“==”用于比较引用
* 类型变量时,“==”两边的变量被显式声明的类型必须是同种类型或有继承关系,即位于
* 继承树的同一个继承分支上,否则编译出错。
* 2、在运行时,Java 虚拟机将根据两边的引用变量实际引用的对象进行比较。
* </pre>
*
* @author CoderDream
*
*/
public class Demo02 {
/**
*
*/
public static void f1() {
Dog dog = new Dog(); // dog变量被声明为Dog类型
Creature creature = dog; // 变量creature和dog引用同一个Dog对象
Animal animal = new Cat(); // animal 变量被声明为 Animal 类型
System.out.println(dog == animal); // 合法,打印false
System.out.println(dog == creature);// 合法,打印false
}
/**
* <pre>
* 这里变量dog被声明为Dog类型,变量cat被声明为Cat类型,Dog类和Cat类之间没有继承关系,
* 因此这两个变量不能用“==”比较。
* </pre>
*/
public static void f2() {
Dog dog = new Dog();
Cat cat = new Cat();
// System.out.println(dog == cat);// 编译出错
}
/**
* @param args
*/
public static void main(String[] args) {
Demo02.f1();
}
}
class Creature {
}
class Animal extends Creature {
}
class Dog extends Animal {
}
class Cat extends Animal {
}
输出结果:
false
true
3、操作符“==”用于数组类型
数组类型也是引用类型,可以用“==”进行比较
代码03:
/**
* Demo03.java
*
* Provider: CoderDream's Studio
*
* History
* Date(DD/MM/YYYY) Author Description
* ----------------------------------------------------------------------------
* Nov 13, 2007 CoderDream Created
*/
package com.coderdream.operator;
/**
* <pre>
* 操作符“==”用于数组类型
* </pre>
*
* @author CoderDream
*
*/
public class Demo03 {
/**
* <pre>
* 数组类型也是引用类型,可以用“==”进行比较
* </pre>
*/
public static void f1() {
// boolean b1 = new int[4] == new long[5];//编译出错,两边类型不一致
boolean b2 = new int[4] == new int[4];// 合法,b2的值为false
System.out.println(b2);
int[] array1 = new int[4];
int[] array2 = array1;
boolean b3 = array1 == array2; // 合法,b3的值为true
System.out.println(b3);
}
/**
* @param args
*/
public static void main(String[] args) {
Demo03.f1();
}
}
输出结果:
false
true
4、equals() 方法
equals() 方法是在 Object 类中定义的方法,它的声明格式如下:
public boolean equals(Object obj)
Object 类的 equals() 方法的比较规则为:当参数 obj 引用的对象与当前对象为同一个对象时,就返回true,否则返回false。
在JDK中有一些类覆盖了 Object 类的equal()方法,它们的比较规则为:
如果两个对象的类型一致,并且内容一致,则返回true。
这些类包括:java.io.File、java.util.Date、java.lang.String、包装类(如java.lang.Integer和java.lang.Double类)。
代码04:
/**
* Demo04.java
*
* Provider: CoderDream's Studio
*
* History
* Date(DD/MM/YYYY) Author Description
* ----------------------------------------------------------------------------
* Nov 13, 2007 CoderDream Created
*/
package com.coderdream.operator;
/**
* @author CoderDream
*
*/
public class Demo04 {
/**
* <pre>
* equals() 方法是在 Object 类中定义的方法,它的声明格式如下:
* public boolean equals(Object obj)
* Object 类的 equals() 方法的比较规则为:当参数 obj 引用的对象与当前对象为
* 同一个对象时,就返回true,否则返回false。
* </pre>
*/
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else {
return false;
}
}
/**
* <pre>
* 1、a1和a2变量引用不同的对象,因此用“==”或 equals() 方法比较的结果都为 false;
* 2、a1和a3变量都引用同一个Dog对象,因此用“==”或equals()方法比较的结果都为true;
* </pre>
*/
public static void f1() {
Animal a1 = new Dog();
Animal a2 = new Cat();
Animal a3 = a1;
System.out.println(a1 == a2); // 打印false
System.out.println(a1.equals(a2)); // 打印false
System.out.println(a1 == a3); // 打印true
System.out.println(a1.equals(a3)); // 打印true
}
/**
* <pre>
* 在JDK中有一些类覆盖了 Object 类的equal()方法,它们的比较规则为:
* 如果两个对象的类型一致,并且内容一致,则返回true。
* 这些类包括:java.io.File、java.util.Date、java.lang.String、
* 包装类(如java.lang.Integer和java.lang.Double类)。
* </pre>
*/
public static void f2() {
Integer int1 = new Integer(1);
Integer int2 = new Integer(1);
String str1 = new String("Hello");
String str2 = new String("Hello");
System.out.println(int1 == int2); // 打印false
System.out.println(int1.equals(int2)); // 打印true
System.out.println(str1 == str2); // 打印false
System.out.println(str1.equals(str2)); // 打印true
}
/**
* <pre>
* Boolean 类是包装类,只要两个Boolean对象的布尔值内容一样,
* equals()方法的比较结果就为true。
* </pre>
*/
public static void f3() {
Boolean b1 = new Boolean(true);
Boolean b2 = new Boolean(true);
if (b1 == b2) {
if (b1.equals(b2)) {
System.out.println("a");
} else {
System.out.println("b");
}
} else {
if (b1.equals(b2)) {
System.out.println("c"); // 执行这段代码
} else {
System.out.println("d");
}
}
}
/**
* <pre>
* b1和obj1被声明为不同的类型,但它们实际引用的是同一个Dog对象,
* 因此用“==”或equals()方法比较的结果都为true。
* </pre>
*/
public static void f4() {
Boolean b1 = new Boolean(true);
Object obj1 = (Object) b1;
if (b1 == obj1) {
if (b1.equals(obj1)) {
System.out.println("a"); // 执行这段代码
} else {
System.out.println("b");
}
} else {
if (b1.equals(obj1)) {
System.out.println("c");
} else {
System.out.println("d");
}
}
}
/**
* <pre>
* Float 和 Double 类型是包装类型,只要两个 Float 对象或两个 Double对象的内容一样,
* equals()方法比较的结果就为true。
* </pre>
*/
public static void f5() {
Float f1 = new Float("10F");
Float f2 = new Float("10F");
Double d1 = new Double("10D");
System.out.println(f1 == f2); // 打印false
System.out.println(f1.equals(f2)); // 打印true
System.out.println(f1.equals(d1)); // 打印false,因为f2和d1不是相同类型
System.out.println(f1.equals(new Float("10"))); // 打印true
}
/**
* <pre>
* 例如以下变量a和b引用不同的String对象,但它们包含的内容都是“helle”,
* 所以a.equals(b)的结果为true;
* 而变量c是字符串数组类型,因此a.equals(c)的结果为false。
* </pre>
*/
public static void f6() {
String a = "hello";
String b = new String(a);
char[] c = { 'h', 'e', 'l', 'l', 'o' };
System.out.println(a == "hello"); // 打印true
System.out.println(a == b); // 打印false
System.out.println(a.equals(b)); // 打印true
System.out.println(a.equals(c)); // 打印false
}
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("----------f1()------------");
Demo04.f1();
System.out.println("----------f2()------------");
Demo04.f2();
System.out.println("----------f3()------------");
Demo04.f3();
System.out.println("----------f4()------------");
Demo04.f4();
System.out.println("----------f5()------------");
Demo04.f5();
System.out.println("----------f6()------------");
Demo04.f6();
}
}
输出结果:
----------f1()------------
false
false
true
true
----------f2()------------
false
true
false
true
----------f3()------------
c
----------f4()------------
a
----------f5()------------
false
true
false
true
----------f6()------------
true
false
true
false
5、在用户自定义的类中也可以覆盖Object类的equals()方法,重新定义比较规则。
代码05:
/**
* Demo05.java
*
* Provider: CoderDream's Studio
*
* History
* Date(DD/MM/YYYY) Author Description
* ----------------------------------------------------------------------------
* Nov 13, 2007 CoderDream Created
*/
package com.coderdream.operator;
/**
* @author CoderDream
*
*/
public class Demo05 {
/**
* @param args
*/
public static void main(String[] args) {
Person p1 = new Person("Tom");
Person p2 = new Person("Tom");
System.out.println(p1 == p2); // 打印 false
System.out.println(p1.equals(p2)); // 打印 true
}
}
class Person {
private String name;
public Person(String name) {
this.name = name;
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object o) {
if (this == o) {
return true;
}
final Person other = (Person) o;
if (this.name.equals(other.name)) {
return true;
} else {
return false;
}
}
}
输出结果:
false
true
6、 instanceof操作符
instanceof操作符用于判断一个引用类型所引用的对象是否是一个类的实例。
instanceof操作符左边的操作元是一个引用类型,右边的操作元是一个类名或接口名。
形式如下:
obj instanceof ClassName
或者:
obj instanceof InterfaceName
例如:
Dog dog = new Dog();
Systom.out.println(dog instanceof XXX);//XXX表示一个类名或接口名
一个类的实例包括类本身的实例,以及所有直接或间接的子类的实例,因此当"XXX"是以下
值时,instanceof 表达式的值为true。
● Dog类
● Dog类的直接或间接父类
● Dog类实现的接口,已经所有父类实现的接口。
代码06:
/**
* Demo06.java
*
* Provider: CoderDream's Studio
*
* History
* Date(DD/MM/YYYY) Author Description
* ----------------------------------------------------------------------------
* Nov 13, 2007 CoderDream Created
*/
package com.coderdream.operator;
/**
* <pre>
* instanceof操作符用于判断一个引用类型所引用的对象是否是一个类的实例。
* instanceof操作符左边的操作元是一个引用类型,右边的操作元是一个类名或接口名。
* 形式如下:
* obj instanceof ClassName
* 或者:
* obj instanceof InterfaceName
* 例如:
* Dog dog = new Dog();
* Systom.out.println(dog instanceof XXX);//XXX表示一个类名或接口名
*
* 一个类的实例包括类本身的实例,以及所有直接或间接的子类的实例,因此当"XXX"是以下
* 值时,instanceof 表达式的值为true。
* ● Dog类
* ● Dog类的直接或间接父类
* ● Dog类实现的接口,已经所有父类实现的接口。
* </pre>
*
*
* @author CoderDream
*
*/
public class Demo06 {
/**
* <pre>
* 由于Animal是Dog的直接父类,Creature类和Object类是Dog的间接父类,
* 因此以下 instanceof 表达式的值为true。
* </pre>
*/
public static void f1() {
Dog dog = new Dog();
System.out.println(dog instanceof Dog); // 打印 true
System.out.println(dog instanceof Animal); // 打印 true
System.out.println(dog instanceof Creature); // 打印 true
System.out.println(dog instanceof Object); // 打印 true
}
/**
* <pre>
* instanceof 右边的操作元也可以是接口名。
* </pre>
*/
public static void f2() {
B b = new B();
System.out.println(b instanceof I); // 打印 true
}
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("-----------f1()-----------");
Demo06.f1();
System.out.println("-----------f2()-----------");
Demo06.f2();
}
}
interface I {
}
class A implements I {
}
class B extends A {
}
输出结果:
-----------f1()-----------
true
true
true
true
-----------f2()-----------
true
7、 instanceof 与多态性
对于引用类型变量,Java 编译器只根据变量被先生声明的类去编译。
instanceof 左边操作元被显式声明的类型与右边操作元必须是同种类或者有继承关系,即位于继承树的同一个继承分支上,否则编译出错。
Dog dog = new Dog();
System.out.println(dog instanceof Cat); // 编译出错
Cat cat = new Cat();
System.out.println(cat instanceof Dog); // 编译出错
instanceof 用于数组类型
boolean b1 = new int[4] instanceof long[]; // 编译出错,两边操作元类型不一致
boolean b2 = new int[4] instanceof int[]; // 合法,b2的值为true
代码07:
/**
* Demo07.java
*
* Provider: CoderDream's Studio
*
* History
* Date(DD/MM/YYYY) Author Description
* ----------------------------------------------------------------------------
* Nov 13, 2007 CoderDream Created
*/
package com.coderdream.operator;
/**
* <pre>
* instanceof 与多态性
* 对于引用类型变量,Java 编译器只根据变量被先生声明的类去编译。
* instanceof 左边操作元被显式声明的类型与右边操作元必须是同种类或者有继承关系,
* 即位于继承树的同一个继承分支上,否则编译出错。
* Dog dog = new Dog();
* System.out.println(dog instanceof Cat); // 编译出错
*
* Cat cat = new Cat();
* System.out.println(cat instanceof Dog); // 编译出错
*
* instanceof 用于数组类型
* boolean b1 = new int[4] instanceof long[]; // 编译出错,两边操作元类型不一致
* boolean b2 = new int[4] instanceof int[]; // 合法,b2的值为true
* </pre>
*
* @author CoderDream
*
*/
public class Demo07 {
/**
* <pre>
* 在运行时,将根据左边操作元实际引用的对象来判断。
* </pre>
*/
public static void f1() {
Animal a = new Dog(); // a 变量被声明为Animal类型,引用Dog对象
System.out.println(a instanceof Animal); // 合法, 打印true
System.out.println(a instanceof Dog); // 合法, 打印true
System.out.println(a instanceof Cat); // 合法, 打印false
}
/**
* <pre>
* 假定Animal类是非抽象类,允许实例化,
*
* </pre>
*/
public static void f2() {
System.out.println((new Demo07()).isInstanceOfAnimal(new Dog())); // 打印fasle
System.out.println((new Demo07()).isInstanceOfAnimal(new Cat())); // 打印fasle
System.out.println((new Demo07()).isInstanceOfAnimal(new Animal())); // 打印true
System.out.println((new Demo07()).isInstanceOfAnimal(new Creature())); // 打印fasle
}
/**
* <pre>
* 假定Animal类是非抽象类,允许实例化,以下判断规则:
* 只有当参数 obj 引用 Animal 类本身的实例,而不是它的子类Dog或Cat多实例时,
* 才返回true。
*
* 如果 obj instanceof Animal为true,那么obj有可能引用 Animal本身、Dog类本身
* 或Cat类本身的实例;
* 如果 obj instanceof Dog 和 obj instanceof Cat均为false,那么 obj 不会引用
* Dog类本身或Cat类本身的实例。
* 如果同时满足这几个条件,就可以得出 obj 引用 Animal 类本身的实例的结论。
* </pre>
*
* @param obj
* @return
*/
public boolean isInstanceOfAnimal(Object obj) {
return obj instanceof Animal && !(obj instanceof Dog)
&& !(obj instanceof Cat);
}
/**
* <pre>
* instanceof 用于数组类型
* </pre>
*/
public static void f3() {
// boolean b1 = new int[4] instanceof long[]; // 编译出错,两边操作元类型不一致
boolean b2 = new int[4] instanceof int[]; // 合法,b2的值为true
System.out.println(b2);
}
/**
* @param args
*/
public static void main(String[] args) {
System.out.println("-----------f1()-----------");
Demo07.f1();
System.out.println("-----------f2()-----------");
Demo07.f2();
System.out.println("-----------f3()-----------");
Demo07.f3();
}
}
输出结果:
-----------f1()-----------
true
true
false
-----------f2()-----------
false
false
true
false
-----------f3()-----------
true
posted on 2007-11-15 12:20
charlie 阅读(331)
评论(0) 编辑 收藏