当前位置: 首页 > news >正文

7.29 Java SE(Java高级 P191-P199)

单元测试

单元测试就是针对最小的功能单元(方法),编写测试代码对其进行正确性测试

Junit快速入门

Junit单元测试框架可以用来对方法进行测试,是由第三方公司开源出来的

可以灵活地编写测试代码,可以针对某个方法执行测试,也支持一键完成对全部方法的自动化测试,且各自独立

不需要程序员去分析测试的结果,会自动生成测试报告出来

package com.itheima.d1_junit;public class StringUtil {public static void printNumber(String name){if(name == null) {System.out.println(0);return;}System.out.println("名字长度是:" + name.length());}public static int getMaxIndex(String data){if(data == null){return -1;}return data.length();}
}
package com.itheima.d1_junit;import org.junit.Assert;
import org.junit.Test;//测试类
public class StringUtilTest {//公共、无参、无返回值@Testpublic void testPrintNumber(){StringUtil.printNumber("admin");StringUtil.printNumber(null);}@Testpublic void testGetMaxIndex(){int index1 = StringUtil.getMaxIndex(null);System.out.println(index1);int index2 = StringUtil.getMaxIndex("admin");System.out.println(index2);//断言机制:程序员可以预测业务方法的结果Assert.assertEquals("方法内部有bug", 4, index2);}}

Junit框架的常见注解

在测试方法执行前执行的方法,常用于初始化资源

在测试方法执行后执行的方法,常用于释放资源 

package com.itheima.d1_junit;import org.junit.*;import java.net.Socket;//测试类
public class StringUtilTest {private static Socket socket;@Beforepublic void test1(){System.out.println("----> test1 Before 执行了");}@BeforeClasspublic static void test11(){System.out.println("----> test11 BeforeClass 执行了");socket = new Socket();}@Afterpublic void test2(){System.out.println("----> test2 After 执行了");}@AfterClasspublic static void test22(){System.out.println("----> test22 AfterClass 执行了");socket.close();}@Testpublic void testPrintNumber(){StringUtil.printNumber("admin");StringUtil.printNumber(null);}@Testpublic void testGetMaxIndex(){int index1 = StringUtil.getMaxIndex(null);System.out.println(index1);int index2 = StringUtil.getMaxIndex("admin");System.out.println(index2);//断言机制:程序员可以预测业务方法的结果Assert.assertEquals("方法内部有bug", 4, index2);}}

 Junit5版本注解名更易懂

反射

反射就是加载类,并允许以编程的方式解剖类中的各种成分(成员变量、方法、构造器等)

获取类

获取Class对象的三种方式

1. Class c1 = 类名.class

2. 调用Class提供方法:public static Class forName(String package);

3. Object提供的方法:public Class getClass();  Class c3 = 对象.getClass();

package com.itheima.d2_reflect;public class Test1Class {public static void main(String[] args) throws Exception {Class c1 = Student.class;System.out.println(c1.getName()); // 全类名com.itheima.d2_reflect.StudentSystem.out.println(c1.getSimpleName()); // StudentClass c2 = Class.forName("com.itheima.d2_reflect.Student");System.out.println(c1 == c2); // trueStudent s = new Student();Class c3 = s.getClass();System.out.println(c1 == c3); // true}
}

获取类的构造器

package com.itheima.d2_reflect;import org.junit.Test;import java.lang.reflect.Constructor;public class Test2Constructor {@Testpublic void testGetConstructors(){//1.获取这个类的Class对象Class c = Student.class;//2.获取类的全部构造器//Constructor[] constructors = c.getConstructors();Constructor[] constructors = c.getDeclaredConstructors();//3.遍历数组中的每个构造器对象for (Constructor constructor : constructors) {System.out.println(constructor.getName() + "--->" + constructor.getParameterCount());}}@Testpublic void testGetConstructor() throws Exception {//1.得到这个类的Class对象Class c = Student.class;//2.获取某个构造器:无参数构造器//Constructor constructor = c.getConstructor();Constructor constructor = c.getDeclaredConstructor();System.out.println(constructor.getName() + "--->" + constructor.getParameterCount());//3.获取有参数构造器Constructor constructor1 = c.getConstructor(String.class, int.class);System.out.println(constructor1.getName() + "--->" + constructor1.getParameterCount());}}

 获取类的构造器的作用:初始化对象返回

@Testpublic void testGetConstructor() throws Exception {//1.得到这个类的Class对象Class c = Student.class;//2.获取某个构造器:无参数构造器//Constructor constructor = c.getConstructor();Constructor constructor = c.getDeclaredConstructor();System.out.println(constructor.getName() + "--->" + constructor.getParameterCount());constructor.setAccessible(true);//禁止检查访问权限,暴力反射,private构造器也可以访问Student student = (Student)constructor.newInstance();System.out.println(student);//3.获取有参数构造器Constructor constructor1 = c.getConstructor(String.class, int.class);System.out.println(constructor1.getName() + "--->" + constructor1.getParameterCount());Student student1 = (Student)constructor1.newInstance("叮当猫", 3);System.out.println(student1);}

获取类的成员变量

获取成员变量的作用是赋值、取值

package com.itheima.d2_reflect;import org.junit.Test;import java.lang.reflect.Constructor;
import java.lang.reflect.Field;public class Test3Field {@Testpublic void testGetField() throws Exception {//1.得到类的Class对象Class c = Student.class;//2.获取类的全部成员变量Field[] fields = c.getDeclaredFields();//3.遍历数组for (Field field : fields) {System.out.println(field.getName() + "--->" + field.getType());}//4.定位某个成员变量Field fName = c.getDeclaredField("name");System.out.println(fName.getName() + "--->" + fName.getType());Field fAge = c.getDeclaredField("age");System.out.println(fAge.getName() + "--->" + fAge.getType());//赋值Student student = new Student();fName.setAccessible(true);fName.set(student, "小明");System.out.println(student);//取值String name = (String) fName.get(student);System.out.println(name);}
}

获取类的成员方法

成员方法的作用是执行 

package com.itheima.d2_reflect;import org.junit.Test;import java.lang.reflect.Method;
import java.util.Objects;public class Test3Method {@Testpublic void testGetMethod() throws Exception {//1.得到Class对象Class c = Student.class;//2.获取类的全部成员方法Method[] methods = c.getDeclaredMethods();//3.遍历for (Method method : methods) {System.out.println(method.getName() + "--->" + method.getParameterCount() + "--->" + method.getReturnType());}//4.获取某个方法对象Method run = c.getDeclaredMethod("run");System.out.println(run.getName() + "--->" + run.getParameterCount() + "--->" + run.getReturnType());Method eat = c.getDeclaredMethod("eat", String.class);System.out.println(eat.getName() + "--->" + eat.getParameterCount() + "--->" + eat.getReturnType());Student student = new Student();run.setAccessible(true);//禁止访问权限Object rs = run.invoke(student);System.out.println(rs);eat.setAccessible(true);Object rs2 = eat.invoke(student, "鱼");System.out.println(rs2);}
}

作用、应用场景

反射的基本作用:可以得到一个类的全部成分然后操作

可以破坏封装性

需求:使用反射做一个简易版的框架,对于任意一个对象,该框架都可以把对象的字段名和对应的值保存到文件中去

分析:1.定义一个方法,可以接收任意对象

           2.每收到一个对象后,使用反射获取该对象的Class对象,然后获取全部的成员变量

           3.遍历成员变量,然后提取成员变量在该对象中的具体值

           4.把成员变量名和其值写出到文件中去

package com.itheima.d2_reflect;import java.io.FileOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Field;public class ObjectFrame {public static void saveObject(Object obj) throws Exception {PrintStream ps = new PrintStream(new FileOutputStream("D:\\java_code\\javasepromax\\junit-reflect-annotation-proxy-app\\src\\data.txt", true));Class c = obj.getClass();String cName = c.getSimpleName();ps.println("----------" + cName + "----------");//从类中获取全部成员变量Field[] fields = c.getDeclaredFields();for (Field field : fields) {String name = field.getName();field.setAccessible(true);String value = field.get(obj)+"";ps.println(name + "=" + value);}}
}
package com.itheima.d2_reflect;import org.junit.Test;public class Test5Frame {@Testpublic void save() throws Exception {Student s1 = new Student("黑马吴彦祖", 45);Teacher t1 = new Teacher("播妞", 3000);ObjectFrame.saveObject(s1);ObjectFrame.saveObject(t1);}
}

注解

注解就是Java代码里的特殊标记,如:@Override、@Test等,作用是让其他程序根据注解信息来决定怎么执行该程序

注解可以用在类、构造器、方法、成员变量、参数等位置处

自定义注解

如果注解中只有一个value属性,使用注解时,value名称可以不写

注解的本质都是一个接口,Java中所有注解都是继承Annotation接口的

@注解(...):其实就是一个实现类对象,实现了该注解以及Annota接口

package com.itheima.d3_annotation;public @interface MyTest1 {String aaa();boolean bbb() default true;String[] ccc();
}
package com.itheima.d3_annotation;public @interface MyTest2 {String value();//特殊属性
}
package com.itheima.d3_annotation;@MyTest1(aaa="牛魔王", ccc={"Java", "HTML"})
//@MyTest2(value = "孙悟空")
//@MyTest2("孙悟空")
public class AnnotationTest1 {@MyTest1(aaa="铁扇公主", ccc={"Python", "Java"})public void test1(){}
}

元注解 

指的是修饰注解的注解

package com.itheima.d3_annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)//当前被修饰的注解只能用在类上
public @interface MyTest3 {
}
package com.itheima.d3_annotation;@MyTest3
public class AnnotationTest2 {@MyTest3public void test(){}//报错
}

注解的解析

就是判断类、方法、成员变量上是否存在注解,并把注解里的内容给解析出来

解析注解:要解析谁上面的注解,就应该先拿到谁,比如要解析类上面的注解,则应该先获取该类的Class对象,再通过Class对象解析其上面的注解;要解析成员方法上面的注解,则应该先获取该成员方法的Method对象,再通过Method对象解析其上面的注解

package com.itheima.d3_annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest4 {String value();double aaa() default 100;String[] bbb();
}
package com.itheima.d3_annotation;@MyTest4(value = "蜘蛛精", aaa = 99.5, bbb = {"至尊宝", "黑马"})
public class Demo {@MyTest4(value = "孙悟空", aaa = 199.9, bbb = {"紫霞", "牛夫人"})public void test1(){}
}
package com.itheima.d3_annotation;import org.junit.Test;import java.lang.classfile.Annotation;
import java.util.Arrays;public class AnnotaTest3 {@Testpublic void parseClass(){//得到Class对象Class c = Demo.class;//判断类上是否包含某个注解if(c.isAnnotationPresent(MyTest4.class)){MyTest4 myTest4 =(MyTest4)c.getDeclaredAnnotation(MyTest4.class);System.out.println(myTest4.value());System.out.println(myTest4.aaa());System.out.println(Arrays.toString(myTest4.bbb()));}}
}

 应用场景——模拟Junit框架

需求:定义若干个方法,只要加了MyTest注解,就会触发该方法执行

分析:1.定义一个自定义注解MyTest,只能注解方法,存活范围是一直存在

           2.定义若干个方法,部分方法加上@MyTest注解,部分不加

           3.模拟一个junit程序,可以触发加了@MyTest注解的方法执行

package com.itheima.d3_annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {
}
package com.itheima.d3_annotation;import java.lang.classfile.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;public class AnnotationTest4 {//@MyTestpublic void test1(){System.out.println("----test1----");}@MyTestpublic void test2(){System.out.println("----test2----");}//@MyTestpublic void test3(){System.out.println("----test3----");}@MyTestpublic void test4(){System.out.println("----test4----");}public static void main(String[] args) throws Exception {AnnotationTest4 a = new AnnotationTest4();//启动程序//1.得到Class对象Class c = AnnotationTest4.class;Method[] methods = c.getDeclaredMethods();for (Method method : methods) {if(method.isAnnotationPresent(MyTest.class)){method.invoke(a);}}}
}

http://www.dtcms.com/a/305417.html

相关文章:

  • Linux 线程概念与控制
  • 继续打卡day6
  • SpringJDBC源码初探-DataSource类
  • 理解“无界队列”与“有界队列”及其适用场景
  • BigemapPro吸附功能 | 绘图共点共边,标绘从此无缝衔接!
  • 【Python】数据可视化之聚类图
  • 进阶向:Manus AI与多语言手写识别
  • 大模型量化004
  • 机器学习-贝叶斯函数(理解版)
  • Xmind 2025下载与保姆级安装教程
  • 数据库-索引
  • Python Day17 常用模块 和 加解密操作 及例题分析
  • window weblogic 解锁
  • Java 9 新特性解析
  • 《零基础入门AI:传统机器学习入门(从理论到Scikit-Learn实践)》
  • 36.Manacher 算法
  • 【n8n】如何跟着AI学习n8n【01】:定制AI老师
  • 【Linux】pthread学习笔记
  • scrapy框架新浪新闻
  • 使用JSON Schema 的 dependencies 实现 LLM 工具调用的参数约束
  • C 语言基础第16天:指针补充
  • 粒子群优化算法(Particle Swarm Optimization, PSO) 求解二维 Rastrigin 函数最小值问题
  • Mysql缓冲池和LRU
  • 关注 Yocto项目实战教程
  • PyCharm插件开发与定制指南:打造个性化开发环境
  • C++ 模板类型传递可行性检测指南
  • 3D打印喷头的基本结构
  • 区间DP求解策略详解
  • cmseasy靶机密码爆破通关教程
  • 第一章 RAG三问