java2_day07 java常用类之Objects类和包装类
2022/4/30 17:42:54
本文主要是介绍java2_day07 java常用类之Objects类和包装类,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Java常用类之Object类、包装类
目录
-
Object类的使用
-
单元测试方法的使用
-
包装类的使用
1 Object类的使用
-
object类包含以下几个方法
-
hashcode() 集合里边有讲
-
toString()
-
clone() 用的较少
-
getClass() 获取当前对象的类,反射讲
-
notify() 多线程里讲
-
wait() 多线程里讲
-
equals()
-
-
Object类是所有Java类的根父类
-
如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类
-
public class Person{
}
等价于
-
public class Person extends Object{
}
-
-
例:method(Object obj){...} //可以接收任何类作为其参数
Person o = new Person();
method(o);
-
程序员可以通过System.gc()或者Runtime.getRuntime().gc()来通知系统进行垃圾回收,会有一些效果,但是系统是否进行回收依然不确定。
-
对象回收之前会先调用finalize方法
面试题:final、finally、finalize的区别?
-
前两个是关键字,finalize是方法,一般不要主动调用。
1.1 Object中equals()方法
面试题:==和equals的区别
package com.xin.java; /** * Created with IntelliJ IDEA. * User: xinxueqi * Date: 2022/4/28 11:24 * Description: * 面试题: == 和 equals()的区别 * 一、 ==运算符: * 1. 可以使用在基本数据类型变量和引用数据类型的变量中 * 2. 如果比较的是基本数据类型变量,比较两个变量保存的数据是否相等。(不一定类型要相同) * 如果比较的是引用数据类型变量,比较两个对象的地址值是否相同。即两个引用是否指向同一个对象实体。 *二、 equals()方法的使用 * 1. 是一个方法,而非运算符 * 2. 只能适用于引用数据类型,(像类才能用点后面加方法的方式)。 * 3. Object中equals()的定义: * public boolean equals(Object obj) { * return this == obj; * } * 说明: Object类中定义的equals()和==作用是相同的,比较两个对象的地址值是否相同。 * 4. 像String、Date、File、包装类等都重写了Object类中的equals()方法。重写以后, * 比较的不是两个引用的地址是否相同,而是比较两个对象的"实体内容"是否相同。 * 5. 通常情况下,我们自定义的类如果使用equals()的话,也是比较两个对象的实体内容是否相同,那么 * 我们就需要对Object类中的equals()方法进行重写。 */ public class EqualsTest { public static void main(String[] args) { int i =10; int j = 10; double d = 10.0; System.out.println(i == j); //TRUE System.out.println(i == d); //TRUE,数值相等就行,和类型无关 boolean b = true; // System.out.println(i == b); //不能和布尔型比较,编译报错 char c = 10; System.out.println(i == c); //TRUE char c1 = 'A'; char c2 = 65; System.out.println(c1 == c2); //TRUE Customer cust1 = new Customer("Tom", 21); Customer cust2 = new Customer("Tom", 21); System.out.println(cust1 == cust2); //false,地址值不同 String str1 = new String("atguigu"); String str2 = new String("atguigu"); System.out.println(str1 == str2); //false,地址值不同 System.out.println("==============================="); //equals()方法测试 System.out.println(cust1.equals(cust2)); //false ,看底层,用的是object里边的equals()方法, 里边用的也是== //重写了customer类之后,结果为true System.out.println(str1.equals(str2)); //TRUE,用的是String里边的equals()方法,String里边进行了重写 } }
Customer类如下:
package com.xin.java; import java.util.Objects; /** * Created with IntelliJ IDEA. * User: xinxueqi * Date: 2022/4/28 11:57 * Description: */ public class Customer { private String name; private int age; public Customer() { } public Customer(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } //重写的原则,比较两个对象的实体内容(即name和age)是否相同 // @Override // public boolean equals(Object obj) { // return super.equals(obj); // } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Customer customer = (Customer) o; return age == customer.age && //省略了this Objects.equals(name, customer.name); //name已经是String字符串了,所以直接可以用equals了 } @Override public int hashCode() { return Objects.hash(name, age); } @Override public String toString() { return "Customer[name = " + name + ", age = " + age + " ]"; } }
-
重写equals()方法的原则
-
对称性:如果x.equals(y)返回是“true” ,那么y.equals(x)也应该返回是“true
-
自反性: x.equas(x)必须返回是“true"
-
传递性:如果x.equals(y)返回是 “true",而且y.equals(z)返回是 “true”,那么z.equals(x)也应该返回是“true';”。
-
一致性:如果x.equals(y)返回是 “true" ,只要x和y内容一直不变, 不管你重复x.equals(y)多少次,返回都是“true”。
-
任何情况下, x.equals(null), 永远返回是“false”;
-
x.equals(和x不同类型的对象)永远返回是“false”
-
练习题1:
package com.xin.java; /** * Created with IntelliJ IDEA. * User: xinxueqi * Date: 2022/4/29 9:48 * Description: * equals()练习1: * 编写Order类,有int型的orderId, String型的orderName, * 相应的getter( )和setter( )方法,两个参数的构造器, * 重写父类的equals( )方法: public boolean equals(Object obi ). * 并判断测试类中创建的两个对象是否相等。 */ public class OrderTest { public static void main(String[] args) { Order order1 = new Order(1001, "AA"); Order order2 = new Order(1001, "BB"); Order order3 = new Order(1001, new String("BB")); //如果重写equals时,name不用equals方法的时候,很可能会出错,因为这里是通过new的方式建立的字符串 System.out.println(order1.equals(order2)); //false System.out.println(order3.equals(order2)); //true } } //Order类也可以新建一个文件 class Order{ private int orderId; private String orderName; public int getOrderId() { return orderId; } public void setOrderId(int orderId) { this.orderId = orderId; } public String getOrderName() { return orderName; } public void setOrderName(String orderName) { this.orderName = orderName; } public Order(int orderId, String orderName) { this.orderId = orderId; this.orderName = orderName; } @Override public boolean equals(Object obj) { if(this == obj){ //如果地址相同,那就不用比了 return true; } if(obj instanceof Order){ //看是不是Order类 Order order = (Order) obj; //如果是,进行一下强转,向下转型,这样才能使用点方法获得属性,从而进行内容的比较 // return this.orderId == order.orderId && this.orderName == order.orderName; //这是错误的 return this.orderId == order.orderId && this.orderName.equals(order.orderName); } return false; } }
练习题2:
-
请根据以下代码自行定义能满足需要的MyDate类, 在MyDate类中覆盖equals方法,使其判断当两个MyDate类型对象的年月日都相同时,结果为true,否则为false。 public boolean equals(Object O)
package com.xin.java; /** * Created with IntelliJ IDEA. * User: xinxueqi * Date: 2022/4/29 10:13 * Description: */ public class MyDateTest { public static void main(String[] args) { MyDate m1 = new MyDate(14, 3, 1976); MyDate m2 = new MyDate(14, 3, 1976); if(m1 == m2){ System.out.println("m1 == m2"); }else{ System.out.println("m1 != m2"); //bingo } if(m1.equals(m2)){ System.out.println("m1 is equal to m2"); //bingo }else{ System.out.println("m1 is not equal to m2"); } } } class MyDate{ private int day; private int month; private int year; public MyDate(int day, int month, int year) { this.day = day; this.month = month; this.year = year; } public int getDay() { return day; } public void setDay(int day) { this.day = day; } public int getMonth() { return month; } public void setMonth(int month) { this.month = month; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } @Override public boolean equals(Object obj) { if(this == obj){ return true; } if(obj instanceof MyDate){ MyDate myDate = (MyDate) obj; return this.year == myDate.year && this.month == myDate.month && this.day == myDate.day; } return false; } }
1.2 toString()方法
-
toString()方法在Object类中定义,其返回值是String类型,返回类名和它的引用地址。
-
在进行String与其它类型数据的连接操作时,自动调用toString()方法 Date now=new Date(); System.out.printn("now="+now);相当于 System.out.printin("now="+now.toString();
-
可以根据需要在用户自定义类型中重写toString(方法),如String类重写了toString()方法,返回字符串的值。 s1="hello"; System.out.printin(s1)//相当于System.out.printin(s1.toString();
-
基本类型数据转换为String类型时,调用了对应包装类的toString()方法
-
int a=10; system.out.printn("a="+a);
-
package com.xin.java; import java.sql.SQLOutput; /** * Created with IntelliJ IDEA. * User: xinxueqi * Date: 2022/4/29 10:32 * Description: * Object中toString()的使用 * 1. 当我们输出一个对象的引用时,实际上就是调用当前对象的toString() * 2. Object类中toString()的定义: * public String toString() { * return this.getClass().getName() + "@" + Integer.toHexString(this.hashCode()); * } * 3. 像String、Date、File、包装类等都重写了Object类中的toString()方法 * 使得在调用对象的toString()时,返回"实体内容"信息。 * 4. 自定义类也可以重写toString()方法,当调用此方法时,返回对象的实体内容。 */ public class toStringTest { public static void main(String[] args) { Customer cust1 = new Customer("Tom", 21); System.out.println(cust1.toString()); //com.xin.java.Customer@27e0e4,输出类名和引用地址 System.out.println(cust1); //结果是一样的,com.xin.java.Customer@27e0e4 //重写之后,输出Customer[name = Tom, age = 21 ] String mm = new String("MM"); System.out.println(mm); //输出MM,因为String类中进行了重写 } }
1.3 Object类综合练习
-
几何类GeometricObject通用属性定义:
package com.xin.java1; /** * Created with IntelliJ IDEA. * User: xinxueqi * Date: 2022/4/29 11:25 * Description: */ public class GeometricObject { protected String color; protected double weight; public GeometricObject() { //空参构造器要求初始化 this.color = "white"; this.weight = 1.0; } public GeometricObject(String color, double weight) { this.color = color; this.weight = weight; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } public double getWeight() { return weight; } public void setWeight(double weight) { this.weight = weight; } }
-
对于GeometricObject子类Circle的要求如下:
package com.xin.java1; /** * Created with IntelliJ IDEA. * User: xinxueqi * Date: 2022/4/29 11:39 * Description: */ public class Circle extends GeometricObject { //子类 private double radius; public Circle() { super(); //已经继承了父类的属性 radius = 1.0; // color = "white"; // weight = 1.0; } public Circle(double radius) { this.radius = radius; } public Circle(String color, double weight, double radius) { super(color, weight); this.radius = radius; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public double findArea(){ //求圆的面积 return 3.14 * radius * radius; } @Override //判断圆的半径是否相等,相等返回true,重写equals()方法 public boolean equals(Object obj) { if(this == obj){ return true; } if(obj instanceof Circle){ Circle circle = (Circle) obj; return this.radius == circle.radius; } return false; } @Override public String toString() { return "Circle{" + "radius=" + radius + '}'; } }
-
测试方法:
package com.xin.java1; /** * Created with IntelliJ IDEA. * User: xinxueqi * Date: 2022/4/29 15:30 * Description: */ public class CircleTest { public static void main(String[] args) { Circle circle = new Circle(2.0); Circle circle2 = new Circle(3.0); System.out.println("颜色是否相等" + circle.color.equals(circle2.color)); //颜色是否相等true // System.out.println(circle.color); //white // System.out.println(circle.getColor()); //white System.out.println("半径是否相等" + (circle.getRadius() == circle2.getRadius())); //半径是基本数据类型,不用equals System.out.println("圆1的半径为:" + circle.toString()); //圆1的半径为:Circle{radius=2.0} System.out.println("圆2的半径为:" + circle2.toString()); //圆2的半径为:Circle{radius=3.0} } }
2 单元测试方法的使用
package com.xin.java1; import org.junit.Test; /** * Created with IntelliJ IDEA. * User: xinxueqi * Date: 2022/4/29 15:51 * Description: * Java中的JUnit单元测试 * 单元测试方法的使用: * 1. 步骤: * 自己打出@Test,导入即可。 * 2. 创建Java类,进行单元测试。 * 此时的Java要求 1. 此类是public的 2. 此类提供公共的无参的构造器 * 3. 此类中声明单元测试方法 * 此时的单元测试方法,方法的权限是public,没有返回值,没有形参 * 4. 此单元测试方法上需要声明注释:@Test * 5. 声明好单元测试方法以后,就可以在方法体内测试相关内容 */ public class JUnitTest { @Test public void testEquals(){ } }
3 包装类的使用
-
针对八种基本数据类型定义相应的引用类型——包装类(封装类)
-
有了类的特点,就可以调用类中的方法,Java才是真正的面向对象
3.1 基本类型、包装类与String类间的转换
3.2 基本数据类型与包装类之间的转换
package com.xin.java2; import org.junit.Test; import java.io.InputStreamReader; /** * Created with IntelliJ IDEA. * User: xinxueqi * Date: 2022/4/29 16:48 * Description: * 包装类的使用: * 1. java提供了8种基本数据类型对应的包装类,使得基本数据类型的变量具有类的特征 * 2. 掌握: 基本数据类型、包装类、String三者之间的相互转换 */ public class WrapperTest { /* JDK 5.0新特性,自动装箱与自动拆箱 */ @Test public void test3(){ int num1 = 10; // method(。。) //此时需要包装类了,需要进行转换 //自动装箱:基本数据类型-->包装类 int num2 = 10; Integer in1 = num2; //基本数据类型直接赋值给包装类的对象了,而不用新建对象 boolean b1 = true; Boolean b2 = b1; //自动拆箱:包装类-->基本数据类型 System.out.println(in1.toString()); //in1是一个对象,可以用。方法 int num3 = in1; //可以直接把对象对应的值给基本数据类型 } public void method(Object obj){ } //包装类-->基本数据类型: 调用包装类的xxxValue() //需求:有时需要用基本数据类型进行加减运算,包装类做不到 @Test public void test2(){ Integer in1 = new Integer(12); int i1 = in1.intValue(); //转换为基本类型 System.out.println(i1 + 1); //13 Float f1 = new Float(12.3f); float f2 = f1.floatValue(); //转换为基本类型 System.out.println(f2 + 1); //13.3 } //基本数据类型-->包装类: 调用包装类的构造器 //需求:转换为包装类才能调用相关的方法 @Test public void test1(){ int num1 = 10; Integer in1 = new Integer(num1); //Integer重写了toString方法了 System.out.println(in1.toString()); //10 Integer in2 = new Integer("123"); System.out.println(in2.toString()); //可以是纯粹数值的字符串,123 Float f1 = new Float(12.3f); Float f2 = new Float("12.3f"); System.out.println(f1.toString()); //12.3 System.out.println(f2); //12.3 Boolean b1 = new Boolean(true); Boolean b2 = new Boolean("true"); Boolean b3 = new Boolean("true123"); //其他类型的这样混写会报异常,可以查看源码 System.out.println(b1); System.out.println(b2); System.out.println(b3); //FALSE Order order = new Order(); System.out.println(order.isMale); //FALSE,默认值 System.out.println(order.isFemale); //NULL,是个类了,不是基本数据类型了 } } class Order{ boolean isMale; Boolean isFemale; }
3.3 基本数据类型包装类与String类之间的转换
-
因为基本数据类型与包装类可以实现自动拆箱和装箱了,暂且把他们看作一个整体。
//String类-->基本数据类型、包装类 :调用包装类的parseXxx() @Test public void test5(){ String str1 = "123"; //错误的情况 // int num1 = (int)str1; // Integer num1 = (Integer)str1; //有子父类的关系才能进行强转 int num2 = Integer.parseInt(str1); System.out.println(num2 + 1); //124 String str2 = "true"; Boolean.parseBoolean(str2); //true } //基本数据类型、包装类-->String类 :调用String重载的valueOf(Xxx xxx) @Test public void test4(){ int num1 = 10; //方式1:连接运算 String str1 = num1 + ""; System.out.println(str1); //输出为10,但是是字符串型的"10" //方式2. float f1 = 12.3f; //基本数据类型转换为String String str2 = String.valueOf(f1); //输出为12.3,但是是字符串型的"12.3" Double d1 = new Double(12.4); String str3 = String.valueOf(d1); //包装类转换为String,和基本数据类型与String之间的转换是一致的。 System.out.println(str3); }
3.4 包装类的面试题
package com.xin.java2; import org.junit.Test; /** * Created with IntelliJ IDEA. * User: xinxueqi * Date: 2022/4/29 20:17 * Description: */ public class InterniewTest { @Test public void test1(){ Object o1 = true ? new Integer(1) : new Double(2.0); //编译的时候,就进行了数据提升,把int型变成了double,所以是1.0 System.out.println(o1); //1.0 } @Test public void test2(){ Object o2; if(true) //直接里边是true了,直接运行 o2 = new Integer(1); else o2 = new Double(2.0); System.out.println(o2); //1 } @Test public void test3(){ Integer i = new Integer(1); Integer j = new Integer(1); System.out.println(i == j); //false Integer m = 1; Integer n = 1; //用的自动装箱 System.out.println(m == n); //true //Integer内部定义了IntegerCache结构,IntegerCache中定义了Integer[]数组,保存了从-128~127范围的整数。 //如果我们使用自动装箱的方式,给Integer赋值的范围在-128~127范围内时,可以直接使用数组中的元素,不用再去new了。 Integer x = 128; //自动装箱预先定义好了-128~127数组,当用128,只能新建 Integer y = 128; System.out.println(x = y); //false } }
3.5 包装类的课后练习
package com.xin.java2; import com.sun.jdi.PathSearchingVirtualMachine; import org.junit.Test; import java.util.Scanner; import java.util.Vector; /** * Created with IntelliJ IDEA. * User: xinxueqi * Date: 2022/4/29 21:06 * Description: * 利用Vector代替数组处理:从键盘读入学生成绩(以负数代表输入结束),找出最高分,并输出学生成绩等级。 * 提示:数组一旦创建,长度就固定不变,所以在创建数组前就需要知道它的长度。 * 而向量类java.util.Vector可以根据需要动态伸缩。 * 创建Vector对象: Vector v=new Vector() ; * 给向量添加元素: v.addElement(Object obi); / /obj必须是对象 * 取出向量中的元素: object * obj=v.elementAt(0); * 注意第一个元素的下标是0,返回值是Object类型的。 * 计算向量的长度: v.size(); * 若与最高分相差10分内: A等; 20分内: B等;30分内: C等;其它: D等 */ public class ScoreTest { public static void main(String[] args) { //使用test没运行起来 System.out.println("请输入学生成绩:"); Scanner scanner = new Scanner(System.in); //从键盘读取成绩 Vector vector = new Vector(); //创建Vector对象,相当于原来的数组 while (scanner.hasNextInt()) { //添加进数组 int score = scanner.nextInt(); //int型转换为包装类 Integer in1 = score; //自动装箱 vector.addElement(in1); } //找出最高分 int max = (Integer) vector.elementAt(0); //强转同时,使用自动拆箱 for (int i = 1; i < vector.size(); i++) { int a = (Integer) vector.elementAt(i);//强转同时,使用自动拆箱 if (max <= a) { max = a; } } // System.out.println("student 0 score is i grade is "); for (int i = 0; i < vector.size(); i++) { //输出成绩 int b = (Integer) vector.elementAt(i); String c = level(b, max); System.out.println("student " + i + " score is " + b + " , " + " grade is " + c); } } public static String level(int score, int max){ //方法,String为返回值属性,里边为形参 if(score <= max && score >= max - 10){ return "A"; }else if(score < max - 10 && score >= max - 20){ return "B"; }else if(score < max - 20 && score >= max - 30){ return "C"; }else { return "D"; } } }
改进:
-
输入时,要规定啥时候停止break,同时出现非法输入,重新输入,使用continue;
-
可以进行循环嵌套,应该可以简化代码
4 复习
-
存在子父类之间的关系才能进行强转,强转指向下转型,这样就可以获得子类的属性和方法。
-
多态性
-
可以理解为一个事物的多种形态
-
向上转型:多态
-
对象的多态性:父类的引用指向子类的对象(或子类的对象赋给父类的引用).
-
举例:
-
Person p = new Man(); //此时还是只有父类的方法,但是如果此时子类对于父类方法进行了重写,就按照子类的进行输出。(详看之前的笔记)
-
Object obj = new Date();
-
-
-
谈谈对多态性的理解?
-
实现代码的通用性
-
Object中定义的public boolean equals(Object obj){},使用equals()的时候,就可以只要是obj子类都可以。
-
抽象类和接口的使用体现了多态性。(抽象类、接口不能实例化)只能通过子类new,这样的话通过多态性,就能使用equals()。
-
-
多态是运行时行为,取一个随机数,编译根本看不出来,只能运行之后才能知道。(要看之前对于多态的讲解了)
-
数组也作为Object的子类出现,可以调用Object类中声明的方法。
这篇关于java2_day07 java常用类之Objects类和包装类的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-24Java中定时任务实现方式及源码剖析
- 2024-11-24Java中定时任务实现方式及源码剖析
- 2024-11-24鸿蒙原生开发手记:03-元服务开发全流程(开发元服务,只需要看这一篇文章)
- 2024-11-24细说敏捷:敏捷四会之每日站会
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解