W6-junit、泛型、枚举、增强for、可变参数、反射[JavaWeb]

1.单元测试Junit

  1.1 测试对象是一个类中的方法

  1.2 junit不是javase的部分,使用时需要导入jar包,myeclipse自带jar包

    1.3 单元测试方法的时候,方法命名规则 public void 方法名(){}

  1.4 使用注解方式运行,在方法的上面@Test

package cn.itcast.test02;

import org.junit.Test;

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

  -当出现绿色条,表示测试通过;红棕色表示测试不通过。

  -@Ignore:表示该方法不进行单元测试

  -@Before:在每个方法之前运行

  -@After:在每个方法之后运行

  -断言(了解):Assert.assertEquals("测试期望的值","方法运行的实际的值");

 

2.泛型

  2.1 泛型是提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛型的java程序后,生成的class文件中将不再带有泛型信息。以此使程序运行效率不受到影响,这个过程称为“擦除”。

  2.2 自定义泛型-泛型方法

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

package cn.itcast.test03;

import java.util.Arrays;

public class TestDemo03 {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //创建一个数组 实现11和13位置交换
        Integer[] arr1={10,11,12,13,14};
        swap1(arr1,1,3);
        
        System.out.println(Arrays.toString(arr1));
        
        
    }
    /*
     * 使用泛型方法 需要定义一个类型 使用大写字母表示 T:这个T表示任意的类型
     * 写在返回值之前 void 之前<T>
     * 表示定义了一个类型 这个类型是T 
     */
    public static <T> void swap1(T[]arr,int a,int b){
        T temp=arr[a];
        arr[a]=arr[b];
        arr[b]=temp;
    }

}

 

  2.3 泛型在类上的使用:

package cn.itcast.test03;

public class TestDemo04 <T>{
    //在类里面可以直接使用T的类型
    T aa;
    public void test11(T bb){
        
    }
    //写一个静态方法 在类上面定义的泛型,不能在静态方法里面使用
    public static <A> void test12(A cc){
        
    }
}

  

3.枚举

  3.1 简介:需要在一定的范围内取值,这个值只能是这个范围内的任意一个

  3.2 现实场景:交通信号灯,有三种颜色,每次只能亮三种颜色的任意一个

package cn.itcast.test04;

public class TestEnum1 {
    private light color;
    
    public void test(){
        this.color=light.GREEN;
    }
}

enum light{
    RED,GREEN,YELLOW;
}

  3.3 枚举的构造方法是私有的

  3.4 特殊枚举-在枚举的类里面有构造方法,抽象方法

package cn.itcast.test04;

public class TestEnum2 {

}
enum Color11{
    RED("red") {
        @Override
        public void print1() {
            // TODO Auto-generated method stub
            
        }
    },
    GREEN("green") {
        @Override
        public void print1() {
            // TODO Auto-generated method stub
            
        }
    },
    YELLOW("green") {
        @Override
        public void print1() {
            // TODO Auto-generated method stub
            
        }
    };
    //带有参数的构造方法
    private Color11(String name){}
    //在枚举里面写了抽象方法后,在每个实例里面都实现抽象方法
    public abstract void print1();
}

 

  3.5 枚举的api(查看api)

 

4.  增强for

  4.1 for(遍历出来的值:要遍历的集合){}

  4.2 数组;实现Iterator接口(list和set),所以可以使用增强for循环

    map不能使用增强for循环,因为它没有实现Iterator接口

  4.3 出现的目的:为了替代迭代器

     增强for的底层就是迭代器

 

5. 可变参数

   5.1 可变参数的定义方法 数据类型...数组的名称

  5.2 源代码

package cn.itcast.test04;

public class TestDemo1 {
    public static void main(String[] args) {
        add1(11,22);
    }
    
    public static void add1(int...nums){
        //nums理解为一个数组,这个数组存储传递过来的参数
//        System.out.println(nums.length);
        int sum=0;
        //遍历数组
        for(int i=0;i<nums.length;i++){
            sum+=nums[i];
        }
        System.out.println(sum);
    }
}

   5.3 注意

  (1)可变参数需要写在方法的参数列表中,不能单独定义

  (2)在方法的参数列表中只能有一个可变参数

  (3)方法的参数裂变中的可变参数,必须放在最后

 

6 反射

  6.1 应用在一些通用性比较高的代码中,后期所学的框架大多是使用反射来实现的

  6.2 在框架开发中,都是基于配置文件开发。在配置文件中配置了类,可以通过反射得到类中的所有内容,可以让类中的某个方法执行

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

package cn.itcast.test05;

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

   6.3 第一步:保存Person.java;

    第二步:编译 Person.class ;

    第三步:JVM把class文件使用类加载器加载到内存中;

    第四步:Class类,class字节码文件在内存中表示;

    如果得到了Class类,可以得到这个类中的所有内容:属性,构造方法,普通方法;

      -使用反射首先得到Class类:(1)类名.class (2)对象.getClass() (3)使用Class.forName("路径")

    属性通过一个类 Field;构造方法通过一个类 Constructor;普通方法通过一个类 Method

  6.4 使用反射来操作类里面的构造方法,属性,普通方法

package cn.itcast.test05;

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

import org.junit.Test;

public class TestDemo1 {
    public static void main(String[] args)throws Exception {
        // TODO Auto-generated method stub
        //获取Class类
        Class class1=Person.class;
        Class class2=new Person().getClass();
        Class class3=Class.forName("cn.itcast.test05.Person");
        
    }
    //使用泛型操作普通方法
    @Test
    public void test4()throws Exception{
        //得到Class
        Class c1=Class.forName("cn.itcast.test05.Person");
        //得到普通方法
//        c1.getDeclaredMethods();//得到所有的普通方法
        Person p4=(Person) c1.newInstance();
        Method m1=c1.getDeclaredMethod("setName", String.class);
        //如果操作的是私有方法,需要设置值是true
//        m1.setAccessible(true);
        //让setName方法执行,执行设置值
        m1.invoke(p4, "youqi");
        System.out.println(p4.getName());
    }
    
    //操作属性
    @Test
    public void test3(){
        try{
            //得到Class
            Class c2=Class.forName("cn.itcast.test05.Person");
            //得到name属性
//            c2.getDeclaredFields();//得到所有的属性
            Person p11=(Person)c2.newInstance();
            Field f1=c2.getDeclaredField("name");
            //设置可以操作私有属性
            f1.setAccessible(true);
            //设置name 的值
            f1.set(p11, "wangwu");//相当于在 p.name="wangwu"
            System.out.println(f1.get(p11));
            
        }catch(Exception e){
            e.printStackTrace();
        }
        
    }
    
    //需求:要对一个诶进行实例化,可以new,若不使用new应该怎么获取?
    //操作有参数的构造方法
    @Test
    public void test2()throws Exception{
        //得到Class
        Class class3=Class.forName("cn.itcast.test05.Person");
        //使用有参数的构造方法
//        class3.getConstructors();//获取所有的构造方法
        //传递的是有参数的构造方法里面的参数类型,类型使用class形式传递
        Constructor cs=class3.getConstructor(String.class,String.class);
        //通过有参数的构造方法设置值
        //通过有参数的构造方法设置Person实例
        Person p1=(Person)cs.newInstance("lisi","100");
        System.out.println(p1.getId()+"..."+p1.getName());
    }
    //操作无参数的构造方法
    @Test
    public void test1()throws Exception{
        //得到Class
        Class class3=Class.forName("cn.itcast.test05.Person");
        //得到Person类的实例
        Person p=(Person)class3.newInstance();
        //设置值
        p.setName("Zhangsan");
        System.out.println(p.getName());
    }

}

  6.5 当操作的方法是静态方法时,因为静态方法的调用方式是 类名.方法名,不需要类的实例;使用反射操作静态方法时候,也不要写实例

m1.invoke(null, "youqi");//直接写null

 

 

 

  

posted on 2019-08-10 11:08  ERFishing  阅读(296)  评论(0编辑  收藏  举报