junit单元测试及jdk5.0新特性:泛型、枚举、静态导入、自动拆装箱、增强for循环、可变参数、反射

junit的使用:

单元测试:测试对象是类中的某个方法

junit不是JavaSE的一部分,需要导入jar包使用,但是myeclipse中自带了junit的jar包。

junit有两个版本,3.x和4.x,单元测试的时候方法命名规则为(方法不能带任何参数):public void 方法名(){}
使用注解的方式运行测试方法:在测试方法名上添加@Test

例:


项目工程组成

TestJunit.java文件内容:

package cn.itcast.test;

public class TestJunit {
    
    public void testAdd(int a, int b){
        System.out.println(a + b);
    }
}

TestDemo.java文件内容:

package cn.itcast.test;

import org.junit.Test;

public class TestDemo {
    //测试方法
    @Test
    public void testAdd(){
        TestJunit testJunit = new TestJunit();
        testJunit.testAdd(2, 3);        
    }
}

选中testAdd()函数,右键点击选中RunAS->JunitTest,结果如下时测试通过:


image.png

要测试所有的方法,则直接点击TestDemo文件的其他位置,右键点击选中RunAS->JunitTest

注解:
@Test:表示参加单元测试
@Ignore:表示忽略,不参加单元测试
@Before:表示在每个带有@Test注解方法的测试运行之前运行
@After:表示在每个带有@Test注解方法的测试运行之后运行

断言(了解):
Assert.assertEquals(期望值, 测试函数运行实际值);

jdk5.0新特性:

jdk版本:1.1 ,1.2,1.4,5.0
泛型、枚举、静态导入、自动拆装箱、增强for循环、可变参数、反射

泛型简介:

为什么使用泛型:


image.png

在集合上使用泛型:集合<类型>
List:List
Set:Set
Map:Map
例:

package cn.itcast.test2;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

public class TestDemo2 {
    @Test
    public void testList(){
        List l = new ArrayList();
        l.add("AAA");
        l.add("BBB");
        l.add("CCC");
        for(String s : l){
            System.out.println(s);
        }
    }
}

注意:在泛型的<>中填的是类,不能填基本数据类型,应该填基本数据类型对应的包装类
基本数据类型 -- 包装类:
byte -- Byte
short -- Short
int -- Integer
long -- Long
float -- Float
double -- Double
char -- Character
boolean -- Boolean

在方法上使用泛型:方法逻辑相同,只是数据类型不同,可使用泛型方法

package cn.itcast.test2;

import java.util.Arrays;

public class TestDemo3 {

    public static void main(String[] args) {
        Integer[] arr1 = {1, 2, 3, 4};
        String[] arr2 = {"a", "b", "c", "d"};
        
        System.out.println(Arrays.toString(arr1));
        Swap(arr1, 1, 3);
        System.out.println(Arrays.toString(arr1));
        
        System.out.println("-------------------------------");
        
        System.out.println(Arrays.toString(arr2));
        Swap(arr2, 1, 3);
        System.out.println(Arrays.toString(arr2));
    }

    private static  void Swap(T[] arr, int i, int j) {
        T temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }

}
运行结果

在类上使用泛型:public class 类名 {}
注意:在类上使用的泛型定义的类型T不能在类中的静态方法上使用。

枚举的简介:

枚举概念:在一定范围内取值,取值只能是该范围类的一个值,例:红绿灯的颜色。

package cn.itcast.test2;

public class TestEnum1 {
    
    private Color color;
    
    public void test(){
        this.color = Color.RED;
    }

}

enum Color {
    RED,GREEN,YELLOW;

枚举类的构造方法必须是私有的。
带参数构造方法的枚举类:

enum Color{
    RED("red"),YELLOW("yellow"),GREEN("green");
    
    private Color(String name){
        
    }
}

枚举的api的操作:查看jdk文档
name():返回枚举名
ordinal():枚举下标,从0开始

静态导入

可以在代码里直接使用静态导入方式,导入静态方法或常量。
import static xx.xx.xx;

package cn.itcast.test2;

import static java.lang.System.out;

public class TestDemo4 {
    public static void main(String[] args){
        out.println("静态导入静态常量out");
    }
}

自动拆装箱:

装箱:把基本数据类型转换为对应的包装类
拆箱:把包装类对象转换成基本数据类型

package cn.itcast.test2;

public class TestDemo4 {
    public static void main(String[] args){
        //自动装箱
        Integer i = 10;
        //自动拆箱
        int m = i;
    }
}

增强for循环:

语法:for(类型 遍历变量 :需要遍历的集合){}

实现Iterable接口即可使用增强for循环
list,set实现了Iterable接口,可以使用增强for循环,map没有实现,不能使用增强for循环

设计增强for循环的目的是为了替代迭代器,增强for循环的底层是用迭代器实现的。

可变参数

语法:例:public void function(int... nums){},nums可以理解为一个存储传递过来的参数的数组
注意:
调用是function()函数的参数只能写在其参数列表中,不能单独定义;
在一个方法的参数列表定义中只能有一个可变参数;
可变参数必须放在其他所有参数的后面,例如add(int a,int b,int... nums);

反射(********要理解********):

反射应用在一些通用性比较高的代码中。
大多数的框架都是使用反射来实现的(面试的时候会问框架底层的实现,涉及反射相关的知识)。

框架开发都是基于配置文件开发的:在配置文件中配置类,通过反射来得到类中的所有内容,或者执行类中的某个方法。

类中的所有内容:属性、无参构造方法、有参构造方法、普通方法

反射的原理:

1、把xxx.java文件保存到本地硬盘;
2、编译.java文件成.class文件;
3、使用jvm,把.class文件通过类加载加载到内存中;
4、基于万事万物皆对象的原则,.class文件在内存中使用Class类表示;
5、当使用反射时,首先需要获取到Class类,得到这个类之后,就可以得到.class文件里面的所有内容,包括属性、构造函数、普通方法;属性通过类Filed表示,构造方法通过类Constructor表示,普通方法通过类Method表示。

获取Class类的三种方式:
package cn.itcast.test2;

import org.junit.Test;

public class TestDemo5 {

    public static void main(String[] args) throws Exception {
        //获取Class类的三种方式
        Class clazz1 = Person.class;
        Class clazz2 = new Person().getClass();
        Class clazz3 = Class.forName("cn.itcast.test2.Person");
    }
}
使用反射来操作类中的构造方法:

Person.java文件内容:

package cn.itcast.test2;

public class Person {
    //属性
    private String name;
    private String id;
    
    //无参构造函数
    public Person(){}
    
    //有参构造函数
    public Person(String name, String id){
        this.name = name;
        this.id = id;
    }
    
    //普通方法
    public String getName(){
        return name;
    }
    
    public void setName(String name){
        this.name = name;
    }
}

TestDemo.java文件的内容:

package cn.itcast.test2;

import java.lang.reflect.Constructor;

import org.junit.Test;

public class TestDemo5 {

    public static void main(String[] args) throws Exception {
        //获取Class类的三种方式
        Class clazz1 = Person.class;
        Class clazz2 = new Person().getClass();
        Class clazz3 = Class.forName("cn.itcast.test2.Person");
    }
    
    //操作无参数构造方法
    @Test
    public void TestConstructor1() throws Exception{
        //首先获取Class
        Class clazz = Class.forName("cn.itcast.test2.Person");
        //使用无参构造方法获取Person类的实例
        Person p = (Person) clazz.newInstance();
    }
    
    //操作有参数的构造方法
    @Test
    public void TestConstructor2() throws Exception{
        //首先获取Class
        Class clazz = Class.forName("cn.itcast.test2.Person");
        //获取传递有参数的构造方法,里面的参数类型使用class形式传递
        Constructor cs = clazz.getConstructor(String.class, String.class);
        //通过有参数的构造方法设置值
        Person p = (Person) cs.newInstance("LiSi", "100");
    }
}
使用反射来操作类中的属性:

在TestDemo.java中添加如下函数:

    //操作属性
    @Test
    public void TestAttribute() throws Exception{
        //得到Class类
        Class c2 = Class.forName("cn.itcast.test2.Person");
        //得到Person类实例
        Person p = (Person) c2.newInstance();
        
        //得到name属性
        //Field[] fs = c2.getDeclaredFields();//表示得到所有的属性集合
        Field f = c2.getDeclaredField("name");
        
        //设置可以操作私有属性name
        f.setAccessible(true);
        
        //设置属性值
        f.set(p, "WangWu");//相当于p.name = "WangWu"
    }
使用反射来操作类中的普通方法:
    //操作普通方法
    @Test
    public void TestCommon() throws Exception{
        //得到Class类
        Class c3 = Class.forName("cn.itcast.test2.Person");
        //得到Person实例
        Person p = (Person) c3.newInstance();
        //得到普通方法
        //c4.getDeclaredMethods();//得到所有的普通方法
        Method m1 = c3.getDeclaredMethod("setName", String.class);
        //让setName方法执行,设置name值
        m1.invoke(p, "NiuQi");
        System.out.println(p.getName());
    }

当操作的方法是静态类的方法时,则不需要获取类的实例,直接写m1.invoke(null,"参数值");

上述内容对应的TestDemo.java文件的完整内容
package cn.itcast.test2;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.junit.Test;

public class TestDemo {

    public static void main(String[] args) throws Exception {
        //获取Class类的三种方式
        Class clazz1 = Person.class;
        Class clazz2 = new Person().getClass();
        Class clazz3 = Class.forName("cn.itcast.test2.Person");
    }
    
    //操作无参数构造方法
    @Test
    public void TestConstructor1() throws Exception{
        //首先获取Class
        Class clazz = Class.forName("cn.itcast.test2.Person");
        //使用无参构造方法获取Person类的实例
        Person p = (Person) clazz.newInstance();
    }
    
    //操作有参数的构造方法
    @Test
    public void TestConstructor2() throws Exception{
        //首先获取Class
        Class clazz = Class.forName("cn.itcast.test2.Person");
        //获取传递有参数的构造方法,里面的参数类型使用class形式传递
        Constructor cs = clazz.getConstructor(String.class, String.class);
        //通过有参数的构造方法设置值
        Person p = (Person) cs.newInstance("LiSi", "100");
        
        System.out.println(p.getName());
    }
    
    //操作属性
    @Test
    public void TestAttribute() throws Exception{
        //得到Class类
        Class c2 = Class.forName("cn.itcast.test2.Person");
        //得到Person类实例
        Person p = (Person) c2.newInstance();
        
        //得到name属性
        //Field[] fs = c2.getDeclaredFields();//表示得到所有的属性集合
        Field f = c2.getDeclaredField("name");
        
        //设置可以操作私有属性name
        f.setAccessible(true);
        
        //设置属性值
        f.set(p, "WangWu");//相当于p.name = "WangWu"
        
        System.out.println(p.getName());
    }
    
    //操作普通方法
    @Test
    public void TestCommon() throws Exception{
        //得到Class类
        Class c3 = Class.forName("cn.itcast.test2.Person");
        //得到Person实例
        Person p = (Person) c3.newInstance();
        //得到普通方法
        //c4.getDeclaredMethods();//得到所有的普通方法
        Method m1 = c3.getDeclaredMethod("setName", String.class);
        //让setName方法执行,设置name值
        m1.invoke(p, "NiuQi");
        System.out.println(p.getName());
    }
}

你可能感兴趣的:(junit单元测试及jdk5.0新特性:泛型、枚举、静态导入、自动拆装箱、增强for循环、可变参数、反射)