day14_Object类丶包装类丶单元测试

Object类

概述

java.lang.Object 类是Java语言中的根类,即所有类的父类。它中描述的所有方法子类(包括数组)都可以使用。在对象实例化的时候,最终找的父类就是Object。如果一个类没有特别指定父类, 那么默认则继承自Object类。例如:


public class MyClass /*extends Object*/ {

// ...

}

根据JDK源代码及Object类的API文档,Object类当中包含的方法有11个。在学习Object类的方法前,我们先回顾下

== :运算符

可以使用在基本数据类型变量和引用数据类型变量中,用“==”进行比较时,符号两边的数据类型必须兼容(可自动转换的基本数据类型除外),否则编译出错。

  • 如果比较的是基本数据类型变量:比较两个变量保存的数据是否相等。(不一定类型要相同)只要两个变量的值相等,即为true
  • 如果比较的是引用数据类型变量:比较两个对象的地址值是否相同.即两个引用是否指向同一个对象实体。只有指向同一个对象时,==才返回true

Object类中的主要结构

     Object类中定义的方法如下

equals方法

  • public boolean equals(Object obj) :指示其他某个对象是否与此对象“相等”。所有类都继承了Object,也就获得了equals()方法。equals是一个方法,而非运算符只能适用于引用数据类型。查看Ojbect类在的源码
   public boolean equals(Object obj) {
        return (this == obj);
    }

我们可以知道以下信息

/*
 参数:
    Object obj:可以传递任意的对象
    == 比较运算符,返回的是一个布尔值 true false
         基本数据类型:比较的是值
         引用数据类型:比价的是两个对象的地址值
     this是谁?那个对象调用的方法,方法中的this就是那个对象;p1调用的equals方法所以this就是p1
     obj是谁?传递过来的参数p2
     this==obj -->p1==p2
*/

结论:

  • Objec类中定义的equals()和==的作用是相同的:比较两个对象的地址值是否相同.即两个引用是否指向同一个对象实体 如果没有覆盖重写equals方法,那么Object类中默认进行 == 运算符的对象地址比较,只要不是同一个对象,结果必然为false。Object类的equals方法,默认比较的是两个对象的地址值,没有意义,所以我们要重写equals方法,比较两个对象的属性。 

对象内容比较

  • 如果希望进行对象的内容比较,即所有或指定的部分成员变量相同就判定两个对象相同,则可以覆盖重写equals方法。

重写equals()方法的原则

  • 对称性:如果x.equals(y)返回是“true”,那么y.equals(x)也应该返回是 “true”。
  • 自反性:x.equals(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”。例如:我们重写自定义类Person的equals方法,代码如下

package demo01;
 
import java.util.Objects;
 
public class Person {
    private String name;
    private int age;
 
    @Override
    public boolean equals(Object o) {
        // 如果对象地址一样,则认为相同
        if (this == o) return true;
        // 如果参数为空,或者类型信息不一样,则认为不同
        if (o == null || getClass() != o.getClass()) return false;
        // 转换为当前类型
        Person person = (Person) o;
        // 要求基本类型相等,并且将引用类型交给java.util.Objects类的equals静态方法取用结果
        return age == person.age && Objects.equals(name, person.name);
    }
//其他代码
}

这段代码充分考虑了对象为空、类型一致等问题,但方法内容并不唯一。大多数IDE都可以自动生成equals方法的代码内容。在IntelliJ IDEA中,可以使用 Code 菜单中的 Generate… 选项,也可以使用快捷键 alt+insert ,并选择 equals() and hashCode() 进行自动代码生成。如下图所示:

                         

                                   

toString() 方法

  • toString()方法在Object类中定义,其返回值是String类型,返回类名和它 的引用地址。 在进行String与其它类型数据的连接操作时,自动调用toString()方法。
Date now=new Date();
System.out.println(“now=”+now); 
//相当于
System.out.println(“now=”+now.toString());
  • 直接打印对象的名字,其实就是调用对象的toString方法
  • 看一个类是否重写了toString,直接打印这个类的对象即可,如果没有重写toString方法那么打印的是对象的对象的类型+@+内存地址值。

由于toString方法返回的结果是内存地址,而在开发中,经常需要按照对象的属性得到相应的字符串表现形式,因此也需要重写它。

覆盖重写

如果不希望使用toString方法的默认行为,则可以对它进行覆盖重写。例如自定义的Person类:

public class Person {
    private String name;
    private int age;
 
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    //其他代码
}

在IntelliJ IDEA中,可以点击 Code 菜单中的 Generate... ,也可以使用快捷键 alt+insert ,点击 toString() 选项。选择需要包含的成员变量并确定。如下图所示:

                                           

finalize方法

程序员可以通过System.gc()或者Runtime.getRuntime().gc()来通知系统进行垃圾回收,会有一些效果,但是系统是否进行垃圾回收依然不确定。垃圾回收机制回收任何对象之前,总会先调用它的finalize方法(如果覆盖该方法,让一个新的引用变量重新引用该对象,则会重新激活对象)。永远不要主动调用某个对象的finalize方法,应该交给垃圾回收机制调用。

其他的方法以后在学习....

包装类(Wrapper)

Java提供了两个类型系统,基本类型与引用类型,使用基本类型在于效率,然而很多情况,会创建对象使用,因为对象可以做更多的功能,如果想要我们的基本类型像对象一样操作,就可以使用基本类型对应的包装类,基本数据类型有了类的特点,就可以调用类中的方法,Java才是真正的面向对象。

                                  

基本类型与对应的包装类对象之间,来回转换的过程称为”装箱“与”拆箱“:

  • 装箱:从基本类型转换为对应的包装类对象。
  • 拆箱:从包装类对象转换为对应的基本类型。

用Integer与 int为例:

  • 基本数值---->包装对象
Integer i = new Integer(4);//使用构造函数函数
Integer iii = Integer.valueOf(4);//使用包装类中的valueOf方法
  • 包装对象---->基本数值
int num = i.intValue();

动装箱与自动拆箱

由于我们经常要做基本类型与包装类之间的转换,从Java 5(JDK 1.5)开始,基本类型与包装类的装箱、拆箱动作可以自动完成。例如:

Integer i = 4;//自动装箱。相当于Integer i = Integer.valueOf(4);
i = i + 5;//等号右边:将i对象转成基本数值(自动拆箱) i.intValue() + 5; 加法运算完成后,再次装箱,把基本数值转成对象。

字符串转换成基本数据类型。

  • 通过包装类的构造器实现:
int i = new Integer(“12”);
  • 通过包装类的parseXxx(String s)静态方法:
Float f = Float.parseFloat(“12.1”);

注意:

  • 如果字符串参数的内容无法正确转换为对应的基本类型,则会抛出 java.lang.NumberFormatException异常。

基本数据类型转换成字符串

  • 调用字符串重载的valueOf()方法:
String fstr = String.valueOf(2.34f);
  • 更直接的方式:

                                    

总结:基本类型、包装类与String类间的转换

                     

软件测试

查询百度百科:软件测试(英语:Software Testing),描述一种用来促进鉴定软件的正确性、完整性、安全性和质量的过程。换句话说,软件测试是一种实际输出与预期输出之间的审核或者比较过程。软件测试的经典定义是:在规定的条件下对程序进行操作,以发现程序错误,衡量软件质量,并对其是否能满足设计要求进行评估的过程。

测试的分类

  • 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值。
  • 白盒测试:需要写代码的。关注程序具体的执行流程。Junit测试属于白盒测试中的一种。

现在我们拿到一个需求,需要测试一下Junit包下的Calculator类代码编写是否正确。代码如下

package Junit;
 
/**
 * 计算器类
 */
public class Calculator {
    /**
     * 加法
     * @param a
     * @param b
     * @return
     */
    public int add(int a, int b){
        return a +b;
    }
 
    /**
     * 
     * @param a
     * @param b
     * @return
     */
    public int sub(int a,int b){
        return  a -b;
    }
}

照以前的知识,我们需要在测试类中,创建Calculator类的对象,在调用Calculator类中编写的方法,查看方法的运行结果和我们期望的结果一样。但是这么做很多的缺点:如果我们要测试多个方法,必须把前面测试好的代码注释掉,以免造成影响。步骤麻烦等等。下面我们就是要在IDEA开发工具中使用Junit单元测试的知识来测试这个类。 

步骤如下

1:创建一个包,存放测试用例。包名建议以.text结尾,并且与要测试的代码存放的包平级。

2:在MyTest包中,创建类(测试用例)。建议类名以Test结尾 

 

3:在测试用例中定义测试方法,建议为test要测试的方法名称,例如要测试add方法,测试方法名称可以为testAdd()。测试方法建议空参和void返回值。

 4:给测试方法加@Test注解,导入junit依赖环境

 

 

代码完成之后,方法代码如下

package MyTest;
 
import org.junit.Test;
 
public class CalculatorTest {
    /**
     * 测试add方法
     */
    @Test
    public void testAdd(){
 
    }
}

5:在测试用例中,创建对象,调用要测试的方法进行测试 

package MyTest;
 
import Junit.Calculator;
import org.junit.Test;
 
public class CalculatorTest {
    /**
     * 测试add方法
     */
    @Test
    public void testAdd(){
        //创建对象
        Calculator c = new Calculator();
        //调用方法
        int result = c.add(1, 3);
    }
}

6:使用会使用断言操作来处理结果, Assert.assertEquals(期望的结果,运算的结果); 

package MyTest;
 
import Junit.Calculator;
import org.junit.Assert;
import org.junit.Test;
 
public class CalculatorTest {
    /**
     * 测试add方法
     */
    @Test
    public void testAdd(){
        //创建对象
        Calculator c = new Calculator();
        //调用方法
        int result = c.add(1, 3);
        //断言操作
        Assert.assertEquals(4,result);
    }
}

7:查看下面,如果是绿色的则代码要测试的内容没有问题,红色则说明代码有错误

 

常用的注解

@Before

  • 修饰的方法会在测试方法之前被自动执行

@After

  • 修饰的方法会在测试方法执行之后自动被执行

代码举例

package MyTest;
 
import Junit.Calculator;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
 
public class CalculatorTest {
    /**
     * 初始化方法:
     * 用于资源申请,所有测试方法在执行之前都会先执行该方法
     */
    @Before
    public void init() {
        System.out.println("init...");
    }
 
    /**
     * 释放资源方法:
     * 在所有测试方法执行完后,都会自动执行该方法
     */
    @After
    public void close() {
        System.out.println("close...");
    }
 
 
    /**
     * 测试add方法
     */
    @Test
    public void testAdd() {
        //1.创建计算器对象
        System.out.println("testAdd...");
        Calculator c = new Calculator();
        //2.调用add方法
        int result = c.add(1, 2);
        //System.out.println(result);
 
        //3.断言  我断言这个结果是3
        Assert.assertEquals(3, result);
 
    }
 
    @Test
    public void testSub() {
        //1.创建计算器对象
        Calculator c = new Calculator();
        int result = c.sub(1, 2);
        System.out.println("testSub....");
        Assert.assertEquals(-1, result);
    }
}

代码执行之后的代码 

发布了20 篇原创文章 · 获赞 7 · 访问量 6616

猜你喜欢

转载自blog.csdn.net/weixin_44462792/article/details/105048129
今日推荐