java基础复习10

2021/9/26 20:11:02

本文主要是介绍java基础复习10,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

java基础复习

网络编程入门

6.4、Junit

  • 测试分类:

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

    • 步骤:定义一个测试类(测试用例)
      • 建议:
        • 测试类名:被测试的类名Test
        • 包名:xxx.xxx.xxx.test
    • 定义测试方法:可以独立运行
      • 建议:
        • 方法名:test测试的方法名
        • 返回值:void
        • 参数列表:空参
    • 给方法加@Test
    • 导入Junit依赖环境
public class Calculator {
        //加法
    public int add(int a,int b){
        return a+b;
    }
        //减法
    public int sub(int a,int b){
        return a-b;
    }

}
public class CalculatorTest {
    /*
    初始化方法,用于资源申请,所有测试方法在执行之前都会先执行该方法
     */
    @Before
    public void init(){
        System.out.println("init......");
    }

    /*
    释放资源方法,在所有测试方法执行完后,都会自动执行该方法
     */
    @After
    public void close(){
        System.out.println("close.....");
    }
    
    @Test
    public void testAdd(){
        //1.创建计算器对象
        Calculator c = new Calculator();
        //2.调用add方法
        int result = c.add(1, 2);
        //3.断言,我断言这个结果是3
        //Junit包下的Assert下的assertEquals方法可以判断结果与输出值是否一致
        Assert.assertEquals(3,result);
    }

    @Test
    public void testSub(){
        Calculator c = new Calculator();
        int result = c.sub(1, 2);
        Assert.assertEquals(-1,result);
    }
}

6.5、反射

反射:框架设计的灵魂

  • 框架∶半成品软件。可以在框架的基础上进行软件开发,简化编码

  • 反射: 将类的各个组成部分封装为其他对象,这就是反射机制

    • 好处:
      • 可以在程序运行过程中,操作这些对象。
      • 可以解耦,捉高程序的可扩展性。
  • 获取class对象的方式:

    • class.forName("全类名"): 将字节码文件加载进内存,返回class对象

      • 多用于配置文件,将类名定义在配置文件中。读取文件,加载类
    • 类名.class : 通过类名的属性class获取

      • 多用于参数的传递
    • 对象.getclass() : getclass()方法在object类中定义。

      • 多用于对象的获取字节码的方式

      结论:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的class对象都是同一个。

public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        //1、class.forName("全类名")
        Class cla = Class.forName("lc.com.domain.Person");
        System.out.println(cla);//class lc.com.domain.Person
        //2、类名.class
        Class cla2 = Person.class;
        System.out.println(cla2);//class lc.com.domain.Person
        //3、对象.getClass()
        Person p = new Person();
        Class cla3 = p.getClass();
        System.out.println(cla3);//class lc.com.domain.Person

        //比较三个对象
        System.out.println(cla==cla2);//true
        System.out.println(cla==cla3);//true

    }
}

Class对象功能:

  • 获取功能
    • 1、获取成员变量们
      • Field[] getFields() 获取所有public修饰的成员变量
      • Field getField(string name) 获取指定名称的public修饰的成员变量
      • Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符
      • Field getDeclaredField(string name)
    • 2、获取构造方法们
      • Constructor<?>[] getConstructors()
      • Constructor getConstructor(类<?>... parameterTypes)
      • Constructor getDeclaredConstructor(类<?>... parameterTypes)
      • Constructor<?>[] getDeclaredConstructors()
    • 3、获取成员方法们
      • Method[] getMethods()
      • Method getMethod(string name,类<?>... parameterTypes)
      • Method[] getDeclaredMethods()
      • Method getDeclaredMethod(string name,类<?>... parameterTypes)
    • 4、获取类名
      • String getName()
  • Field :成员变量
    • 操作:
      • 设置值
        • void set(object obj,object value)
      • 获取值
        • get(object obj)
      • 忽略访问权限修饰符的安全检查
        • setAccessible(true):暴力反射
public class ReflectDemo02 {
    public static void main(String[] args) throws Exception {
        Class personClass = Person.class;
        Field[] fields = personClass.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }

        System.out.println("----------------");
        Field a = personClass.getField("a");
        //获取成员变量a的值
        Person p = new Person();
        Object value = a.get(p);
        System.out.println(value);

        //设置A的值
        a.set(p,"张三");
        System.out.println(p);

        System.out.println("--------------");
        //Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符
        Field[] declaredFields = personClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        Field b = personClass.getDeclaredField("b");
        //忽略访问权限惨饰符的安全检查
        b.setAccessible(true);//暴力反射
        Object value2 = b.get(p);
        System.out.println(value2);
    }
}
  • Constructor:构造方法
    • 创建对象:
      • T newInstance(object. .. initargs)
      • 如果使用空参数构造方法创建对象,操作可以简化: Class对象的newInstance方法
public class ReflectDemo03 {
    public static void main(String[] args) throws Exception {
        Class personClass = Person.class;
        //有参构造器
        Constructor constructor = personClass.getConstructor(String.class, int.class);
        System.out.println(constructor);
        //创建对象
        Object o = constructor.newInstance("张三", 23);
        System.out.println(o);

        System.out.println("-----------------");
        //无参构造器
        Constructor constructor1 = personClass.getConstructor();
        System.out.println(constructor1);
        Object o1 = constructor1.newInstance();
        System.out.println(o1);

        //简化版无参构造器
        Object o2 = personClass.newInstance();
        System.out.println(o2);
    }
}
  • Method :方法对象
    • 执行方法
      • object invoke(object obj, object. .. args)
    • 获取方法的名称
      • String getName :获取方法名
public class ReflectDemo04 {
    public static void main(String[] args) throws Exception {
        Class personClass = Person.class;
        //获取指定名称的方法
        Method eat_method = personClass.getMethod("eat");
        Person p = new Person();
        //执行方法
        eat_method.invoke(p);

        Method eat_method2 = personClass.getMethod("eat", String.class);
        eat_method2.invoke(p,"菠萝古老肉");

        //获取所有public修饰的方法
        Method[] methods = personClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);//除了本身,还会显示父类Object的方法
            //获取方法名
            String name = method.getName();
            System.out.println(name);
        }

        //获取类名
        String className = personClass.getName();
        System.out.println(className); //lc.com.domain.Person
    }
}

案例:

需求: 写一个"框架",不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中任意方法

  • 实现:
    • 配置文件
    • 反射
  • 步骤:
    • 将需要创建的对象的全类名和需要执行的方法定义在配置文件中
    • 在程序中加载读取配置文件
    • 使用反射技术来加载类文件进内存
    • 创建对象
    • 执行方法
className=lc.com.domain.Person
methodName=eat
public class ReflectTest {
    public static void main(String[] args) throws Exception {
        //1、加载配置文件
        //1.1、创建Properties对象
        Properties pro = new Properties();
        //1.2、加载配置文件,转换为一个集合
        //1.2.1、获取class目录下的配置文件
        ClassLoader classLoader = ReflectTest.class.getClassLoader();
        InputStream ls = classLoader.getResourceAsStream("pro.properties");
        pro.load(ls);

        //2、获取配置文件中定义的数据
        String className = pro.getProperty("className");
        String methodName = pro.getProperty("methodName");

        //3、加载该类进内存
        Class cla = Class.forName(className);
        //4、创建对象
        Object obj = cla.newInstance();
        //5、获取方法对象
        Method method = cla.getMethod(methodName);
        //6、执行方法
        method.invoke(obj);
    }
}

6.6、注解

  • 概念:说明程序的。给计算机看的

  • 注释:用文字描述程序的。给程序员看的

  • 定义:注解(Annotation),也叫元数据。一种代码级别的说明。它是 JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元秦进行说明,注释。

  • 作用分类:

    • 编写文档: 通过代码里标识的元数据生成文档【生成文档doc文档】
    • 代码分析: 通过代码里标识的元数据对代码进行分析【使用反射】
    • 编译检查: 通过代码里标识的元数据让编译器能够实现基本的编译检查【override】
  • JDK中预定义的一些注解:

    • @Override :检测被该注解标注的方法是否是继承自父类(接口)的
    • @Deprecated :该注解标注的内容,表示已过时
    • @Suppresswarnings :压制警告
      • 一般传递参数all,格式:@Suppresswarnings("all")
  • 自定义注解:

    • 格式:

      • 元注解

      • public @interface 注解名称{

        ​ 属性列表

        }

    • 本质:注解本质上就是一个接口,该接口默认继承Annotation接口

      • public interface MyAnno extends java.lang.annotation.Annotation {}
    • 属性:接口中的抽象方法

      • 1、属性的返回值类型
        • 基本数据类型
        • String
        • 枚举
        • 注解
        • 以上类型的数组
      • 2、定义了属性,在使用时需要给属性赋值
        • 如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值。
        • 如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可
        • 数组赋值时,值使用{}包裹。如果数组中只有一个值,则{}省略
    public enum Person {
        p1,p2;
    }
    
    public @interface MyAnno2 {
    }
    
    public @interface MyAnno {
        int show1();
        String show2() default "张三";
        String[] str();
        Person per();
        MyAnno2 myanno2();
    }
    
    public class Demo01 {
        @MyAnno(show1 = 1,str = {"aaa","bb"},per = Person.p1,myanno2 = @MyAnno2)
        public void show(){
        }
    }
    
    • 元注解:用于描述注解的注解
      • @Target :描述注解能够作用的位置
        • ElementType取值
          • TYPE :可以作用于类上
          • METHOD :可以作用于方法上
          • FIELD:可以作用于成员变量上
      • @Retention :描述注解被保留的阶段
        • @Retention(RetentionPolicy.RUNTIME):当前被描述的注解,会保留到class字节码文件中,并被Jvm读取到
      • @Documented:描述注解是否被抽取到api文档中
      • @Inherited:描述注解是否被子类继承
@Target(value = {ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyAnno3 {
}
  • 在程序使用(解析)注解∶获取注解中定义的属性值
    • 获取注解定义的位置的对象 (class,Method,Field)
    • 获取指定的注解
      • getAnnotation(class)
    • 调用注解中的抽象方法获取配置的属性值
public class Demo1 {
    public void show(){
        System.out.println("show...Demo1");
    }
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Peo {
    String className();
    String methodName();
}
@Peo(className = "lc.com.demo11.Demo1",methodName = "show")
public class ReflectTest {
    public static void main(String[] args) throws Exception {
        //1、解析注解
        //1.1、获取该类的字节码文件对象
        Class<ReflectTest> reflectTestClass = ReflectTest.class;
        //2、获取上边的注解对象
        //其实就是在内存中生成了一个该注解接口的子类实现对象
        /*
        public class ProImpl implement Pro{
            public String className(){
                 return "lc.com.demo11.Demo1";
            }
            public String methodName(){
                return "show";
            }
        }
         */
        Peo an = reflectTestClass.getAnnotation(Peo.class);
        //3、调用注解对象中定义的抽象方法,获取返回值
        String className = an.className();
        String methodName = an.methodName();
        System.out.println(className);
        System.out.println(methodName);

        //4、加载该类进内存
        Class cla = Class.forName(className);
        //5、创建对象
        Object obj = cla.newInstance();
        //6、获取方法对象
        Method method = cla.getMethod(methodName);
        //7、执行方法
        method.invoke(obj);

    }
}


这篇关于java基础复习10的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程