【Java】Junit、反射和注解的笔记

1 Junit

黑盒测试:不需要写代码,给输入值,看程序输出是否符合期望
白盒测试:需要写代码,关注程序具体的执行流程
Junit —> 白盒测试

步骤

  1. 定义一个测试类(测试用例)
    【命名:类名+Test】【包名:xxx.xx.xx.test】
  2. 定义测试方法,可以独立运行
    【命名:test+测试的方法】【返回值:void】【参数列表:空参】
  3. 给方法加注解@Test
  4. 导入Junit的依赖环境

判断结果
5. 断言:Assert.assertEquals(expected,result);
6. 红失败,绿成功

@Before注解,所有测试方法前会先执行,初始化申请资源方法可以用
@After注解,所有测试方法执行后执行,释放资源方法可以用

2 反射

反射:框架设计的灵魂,将类的各个组成成分
框架:半成品软件,可以在框架的基础上进行软件的开发,简化编码

Java代码在计算机中经历的三个阶段
Java文件 —> Javac编译 —>class文件【Source源代码阶段】 —> 类加载器Class.Loader —> Class类对象 【Class类对象阶段】—> 创建对象 —> Xxxx对象 【Runtime运行时阶段】

反射的好处

  1. 在程序运行过程中,操作这些对象
  2. 可以解耦,提高程序的可扩展性

获取字节码Class对象的三种方式

  1. Class.forName(“全类名”):将字节码文件加载进内存,返回class对象
  2. 类型.class:通过类名的属性class获取
  3. 对象.getClass() :getClass()方法在Object类中定义着
    public static void main(String[] args) throws ClassNotFoundException {//1. Class.forName("全类名"):将字节码文件加载进内存,返回class对象Class cls = Class.forName("reflect.Person");System.out.println(cls);//2. 类型.class:通过类名的属性class获取Class cls2 = Person.class;System.out.println(cls2);//3. 对象.getClass() :getClass()方法在Object类中定义着Class cls3 = new Person().getClass();System.out.println(cls3);System.out.println(cls == cls2);//trueSystem.out.println(cls == cls3);//true}

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

方法1多用于配置文件,将类名定义在配置文件中,读取文件,加载类
方法2多用于参数的传递
方法3多用于对象的获取字节码的方式

class对象的功能

  1. 获取成员变量们
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {Class cls = Person.class;Field[] fields = cls.getFields();//获取所有public修饰的成员变量System.out.println(Arrays.toString(fields));Field school = cls.getField("school");//获取指定的public修饰的成员变量System.out.println(school);Person p = new Person();//获取成员变量school的值Object o = school.get(p);System.out.println(o);//null//设置成员变量school的值school.set(p,"张三小学");System.out.println(p);//Person{name='null', age=0, school='张三小学'}Field[] declaredFields = cls.getDeclaredFields();//获取所有的成员变量for(Field field: declaredFields){System.out.println(field);}//获取私有成员变量的值Field name = cls.getDeclaredField("name");//获取指定的成员变量//访问私有成员前 要忽略访问权限修饰符的安全检查name.setAccessible(true);//暴力反射Object o1 = name.get(p);System.out.println(o1);//null}
  1. 获取构造方法们
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {Class cls = Person.class;//全参构造Constructor constructor = cls.getConstructor(String.class, int.class);System.out.println(constructor);//创建对象Object obj = constructor.newInstance("张三", 19);System.out.println(obj);//空参构造Constructor constructor2 = cls.getConstructor();System.out.println(constructor2);Object obj2 = constructor2.newInstance();System.out.println(obj2);//空参构造一般用这个 简化版Object obj3 = cls.newInstance();System.out.println(obj3);}
  1. 获取成员方方法们
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {Class cls = Person.class;//eat方法为空参Method eat = cls.getMethod("eat");Person p = new Person();//执行方法eat.invoke(p);//eat方法中有一个String类型的参数Method eat2 = cls.getMethod("eat", String.class);eat2.invoke(p," food");//获取所有public修饰的方法Method[] methods = cls.getMethods();for(Method m : methods){System.out.println(m.getName());//除了类自己的方法,Object的方法也存在其中}}
  1. 获取类名

获取的是全类名

    public static void main(String[] args)  {Class cls = Person.class;String name = cls.getName();System.out.println(name);//reflect.Person}

案例:框架类
在不改变该类的任何代码的前提下,可以帮助我们创建任意类的对象并执行任意方法

实现:1. 配置文件 2.反射

步骤:

  1. 将需要创建的对象的全类名和需要执行的方法定义在配置文件中
  2. 在程序中加载读取配置文件
  3. 使用反射技术来加载类文件进内存
  4. 创建对象
  5. 执行方法

创建配置文件 xxx.properties
修改配置文件就可以选择使用的类和方法

className=reflect.Student//全类名
methodName=learn
public class ReflectTest {//在不改变该类的任何代码的前提下,可以帮助我们创建任意类的对象并执行任意方法public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {//1.加载配置文件//1.1创建Properties对象Properties pro = new Properties();//1.2加载配置文件,转换为一个集合//1.2.1获取class目录下的配置文件ClassLoader classLoader = ReflectTest.class.getClassLoader();InputStream is = classLoader.getResourceAsStream("pro.properties");pro.load(is);//2.获取配置文件中定义的数据String className = pro.getProperty("className");String methodName = pro.getProperty("methodName");//3.加载该类进内存Class cls = Class.forName(className);//4.创建对象Object obj = cls.newInstance();//5.获取方法对象Method method = cls.getMethod(methodName);//6.执行方法method.invoke(obj);}
}

运行执行的是配置文件里对应的类和类的方法

3 注解

定义:Annotation,也叫元数据,一种代码级别的说明,JDK1.5后的新特性,与类、接口、枚举在同一层子,可以声明在包、类、字段、方法、局部变量和方法参数等前面,用来对这些元素进行说明,注释。

概念:JDK1.5之后的新特性,用来说明程序

作用分类

  1. 编译检查:让编译器实现基本的编译检查 【@Override @FunctionalInterface】
  2. 代码分析:通过代码标识的注解对代码进行分析【使用反射】
  3. 编写文档:通过代码表示的注解生产文档【javadoc文档】

JDK的内置注解

  1. @Override:检测被该注解标注的方法是否是继承自父类/父接口的
  2. @Deprecated:将该注解标注的内容,表示已过时
  3. @SuppressWarnings :压制警告 @SuppressWarnings(“all”)写在类上方

自定义注解

  • 格式:
    元注解
    public @interface 注解名称{}

注解的本质:是一个接口 默认继承自Annotation接口
public interface javadoc.MyAnno extends java.lang.annotation.Annotation {}

注解的属性:接口中的抽象方法

要求:

  1. 属性的返回值类型有【基本数据类型 String 枚举 注解 以上类型的数组】,不可以为自定义类和void。
  2. 定义了属性,在使用时需要给属性赋值。如果在定义时,分号前写上default “默认值”,可以不赋值
  3. 如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义。

元注解:用来描述注解的注解

  • @Target:描述注解能够作用的位置
    ElementType的取值:
    TYPE:可以作用于类上
    METHOD:可以作用于方法上
    FILED:可以作用于成员变量上
@Target(value = ElementType.TYPE)
  • @Retention:描述注解被保留的阶段
    RetentionPolicy的取值:
    RUNTIME:当前被描述的注解,会保留到class字节码文件中,并被JVM读取到。
    CLASS:
    SOURCE:
@Retention(RetentionPolicy.RUNTIME)
  • @Documented:描述注解是否被抽取到api文档中
  • @Inherited:描述注解是否被子类继承

解析注解

  1. 获取注解定义的位置对象(Class, Method, Field)
  2. 获取指定的注解:getAnnotation(Class)
    Pro annotation = reflectTestClass.getAnnotation(Pro.class);
  3. 调用注解中的抽象方法来获取配置的属性值

定义注解

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Pro {String className();String methodName();
}

自定义类

public class Demo01 {public void show(){System.out.println("demo1...show");}
}

定义框架类

@Pro(className = "reflect.Demo01",methodName = "show")
public class ReflectTest {//在不改变该类的任何代码的前提下,可以帮助我们创建任意类的对象并执行任意方法public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {//1.解析注解//1.1 获取该类的字节码文件对象Class<ReflectTest> reflectTestClass = ReflectTest.class;//2.获取注解对象,在内存中生产了一个该注解接口的子类实现对象/*public class ProImpl implements Pro{public String className(){return "reflect.Demo01";}public String methodName(){return "show";}}*/Pro annotation = reflectTestClass.getAnnotation(Pro.class);//3.调用注解对象中定义的抽象方法获取返回值String className = annotation.className();String methodName = annotation.methodName();System.out.println(className);System.out.println(methodName);//4.加载类进内存Class cls = Class.forName(className);//5.创建对象Object obj = cls.newInstance();//6.获取方法对象Method method = cls.getMethod(methodName);method.invoke(obj);}
}

注解案例:简单的测试框架

定义Check注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Check {
}

定义类

package demo;public class Calculator {//加法@Checkpublic void add(){String str = null;str.toString();System.out.println("1 + 0 =" + (1 + 0));}//减法@Checkpublic void sub(){System.out.println("1 - 0 =" + (1 - 0));}//乘法@Checkpublic void mul(){System.out.println("1 * 0 =" + (1 * 0));}//除法@Checkpublic void div(){System.out.println("1 / 0 =" + (1 / 0));}public void show(){System.out.println("no bug...");}
}

测试类-解析程序

public class TestCheck {public static void main(String[] args) throws IOException {//1.创建计算器对象Calculator c = new Calculator();//2.获取字节码文件对象Class cls = c.getClass();//3.获取所有方法Method[] methods = cls.getMethods();BufferedWriter bw = new BufferedWriter(new FileWriter("bug.txt"));//4.判断方法上是否有check注解int num = 0;for(Method method: methods){if(method.isAnnotationPresent(Check.class)){//5.有就执行方法try{method.invoke(c);//6.捕获异常}catch (Exception e){num++;bw.write(method.getName()+"方法出异常了");bw.newLine();bw.write("异常的名称:"+ e.getCause().getClass().getSimpleName());bw.newLine();bw.write("异常的原因:"+e.getCause().getMessage());bw.newLine();bw.write("-----------------------------");bw.newLine();}}}bw.write("本次测试一共出现了"+num+"次异常");bw.flush();bw.close();}
}

bug.txt文件

add方法出异常了
异常的名称:NullPointerException
异常的原因:null
-----------------------------
div方法出异常了
异常的名称:ArithmeticException
异常的原因:/ by zero
-----------------------------
本次测试一共出现了2次异常

4 小结

  1. 大多数时候,我们会使用注解,而不是自定义注解
  2. 注解是给编译器和解析程序用的
  3. 注解不是程序的一部分

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/480940.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

我对Spring的理解

1、什么是Spring&#xff1f; Spring是Java企业级应用的开源开发框架。Spring主要用来开发Java应用&#xff0c;但是有些扩展是针对构建J2EE平台的web应用。Spring框架目标是简化Java企业级应用开发&#xff0c;并通过POJO为基础的编程模型促进良好的编程习惯。 2、使用Spring…

k-means+python︱scikit-learn中的KMeans聚类实现( + MiniBatchKMeans)

版权声明&#xff1a;博主原创文章&#xff0c;微信公众号&#xff1a;素质云笔记,转载请注明来源“素质云博客”&#xff0c;谢谢合作&#xff01;&#xff01; https://blog.csdn.net/sinat_26917383/article/details/70240628 </div><link rel"stylesh…

想让推荐和搜索引擎更聪明?基于知识图谱的篇章标签生成

一只小狐狸带你解锁NLP/ML/DL秘籍正文来源&#xff1a;丁香园大数据NLP 老板&#xff5e;我们的推荐系统笨笨的你怎么对文档处理的这么糙&#xff01;抽个关键词就应付过去了&#xff1f;啊啊啊我错惹&#xff0c;那那&#xff0c;不用关键词用什么呢&#xff1f;知识图…

论文浅尝 | Dynamic Weighted Majority for Incremental Learning

Yang Lu , Yiu-ming Cheung , Yuan Yan Tang. Dynamic Weighted Majority for Incremental Learning ofImbalanced Data Streams with Concept Drift. In Proceedings of the Twenty-Sixth International Joint Conference on Artificial Intelligence (IJCAI-17)论文链接&…

【JavaWeb】数据库基础复习

1 MySQL 数据库特点&#xff1a; 持久化存储数据&#xff0c;数据库就是一个文件系统便于存储和管理数据使用统一的方式操作数据库 启动MySQL服务&#xff1a; 管理员cmd&#xff1a;net start mysql 停止MySQL服务&#xff1a; 管理员cmd&#xff1a;net stop mysql 打开服…

Python的多行输入与多行输出

因为在OJ上做编程&#xff0c;要求标准输入&#xff0c;特别是多行输入。特意查了资料&#xff0c;自己验证了可行性。if __name__ "__main__":strList []for line in sys.stdin: #当没有接受到输入结束信号就一直遍历每一行tempStr line.split()#对字符串利用空…

微服务Dubbo和SpringCloud架构设计、优劣势比较

一、微服务介绍 微服务架构是互联网很热门的话题&#xff0c;是互联网技术发展的必然结果。它提倡将单一应用程序划分成一组小的服务&#xff0c;服务之间互相协调、互相配合&#xff0c;为用户提供最终价值。虽然微服务架构没有公认的技术标准和规范或者草案&#xff0c;但业界…

搜索引擎核心技术与算法 —— 词项词典与倒排索引优化

一只小狐狸带你解锁NLP/ML/DL秘籍作者&#xff1a;QvQ老板&#xff5e;我会写倒排索引啦&#xff01;我要把它放进咱们自研搜索引擎啦&#xff01;我呸&#xff01;你这种demo级代码&#xff0c;都不够当单元测试的&#xff01;嘤嘤嘤&#xff0c;课本上就是这样讲的呀?!来来&…

论文浅尝 | Distant Supervision for Relation Extraction

Citation: Ji,G., Liu, K., He, S., & Zhao, J. (2017). Distant Supervision for RelationExtraction with Sentence-Level Attention and Entity Descriptions. Ai,3060–3066.动机关系抽取的远程监督方法通过知识库与非结构化文本对其的方式&#xff0c;自动标注数据&am…

使用sklearn做单机特征工程

目录 1 特征工程是什么&#xff1f;2 数据预处理  2.1 无量纲化    2.1.1 标准化    2.1.2 区间缩放法    2.1.3 标准化与归一化的区别  2.2 对定量特征二值化  2.3 对定性特征哑编码  2.4 缺失值计算  2.5 数据变换  2.6 回顾3 特征选择  3.1 Filte…

【JavaWeb】JDBC的基本操作和事务控制+登录和转账案例

1 JDBC操作数据库 1.1 连接数据库 首先导入jar包到lib public class JdbcDemo1 {public static void main(String[] args) throws ClassNotFoundException, SQLException {//1.注册驱动Class.forName("com.mysql.jdbc.Driver");//2.获取数据库连接对象Connection…

Restful、SOAP、RPC、SOA、微服务之间的区别

一、介绍Restful、SOAP、RPC、SOA以及微服务 1.1、什么是Restful&#xff1f; Restful是一种架构设计风格&#xff0c;提供了设计原则和约束条件&#xff0c;而不是架构&#xff0c;而满足这些约束条件和原则的应用程序或设计就是 Restful架构或服务。 主要的设计原则&#xf…

详解深度语义匹配模型DSSM和他的兄弟姐妹

一只小狐狸带你解锁NLP/ML/DL秘籍正文作者&#xff1a;郭耀华正文来源&#xff1a;https://www.cnblogs.com/guoyaohua/p/9229190.html前言在NLP领域&#xff0c;语义相似度的计算一直是个难题&#xff1a;搜索场景下Query和Doc的语义相似度、feeds场景下Doc和Doc的语义相似度、…

行业新闻 | 阿里发力知识图谱研究 悉数囊括顶尖学者探讨合作

12 月 20 日&#xff0c;阿里巴巴联合中国中文信息学会语言与知识计算专委会(KG专委)举办的知识图谱研讨会在杭州召开。研讨会由阿里巴巴集团副总裁墙辉&#xff08;花名&#xff1a;玄难&#xff09;主持&#xff0c;国内知识图谱领域多位顶级专家参加此次研讨会。在阿里巴巴持…

Kaggle入门,看这一篇就够了

New Update&#xff1a;之前发表了这篇关于 Kaggle 的专栏&#xff0c;旨在帮助对数据科学( Data Science )有兴趣的同学们更好的了解这个平台。专栏发表至今收到了不少的关注和肯定&#xff0c;还有很多小伙伴私信相关的问题。因此&#xff0c;我特邀了一位海外一线 Data Scie…

【JavaWeb】JDBC优化 之 数据库连接池、Spring JDBC

1 数据库连接池 为什么要使用数据库连接池&#xff1f; 数据库连接是一件费时的操作&#xff0c;连接池可以使多个操作共享一个连接使用连接池可以提高对数据库连接资源的管理节约资源且高效 概念&#xff1a;数据库连接池其实就是一个容器&#xff0c;存放数据库连接的容器…

Java远程通讯技术及原理分析

在分布式服务框架中&#xff0c;一个最基础的问题就是远程服务是怎么通讯的&#xff0c;在Java领域中有很多可实现远程通讯的技术&#xff0c;例如&#xff1a;RMI、MINA、ESB、Burlap、Hessian、SOAP、EJB和JMS等&#xff0c;这些名词之间到底是些什么关系呢&#xff0c;它们背…

CUDA层硬件debug之路

前记 众所周知&#xff0c;夕小瑶是个做NLP的小可爱。 虽然懂点DL框架层知识&#xff0c;懂点CUDA和底层&#xff0c;但是我是做算法的哎&#xff0c;平时debug很少会遇到深度学习框架层的bug&#xff08;上一次还是三年前被pytorch坑&#xff09;&#xff0c;更从没遇到过CUDA…

研讨会 | 知识图谱大咖云集阿里,他们都说了啥

前言12月20日&#xff0c;由阿里巴巴联合中国中文信息学会语言与知识计算专委会(KG专委)举办的知识图谱研讨会在杭州召开。研讨会由阿里巴巴集团副总裁墙辉&#xff08;玄难&#xff09;主持&#xff0c;知识图谱领域国内知名专家参与了此次研讨。在阿里巴巴持续发力知识图谱这…

置信区间、P值那点事

在假设检验中&#xff0c;我们常常看到跟P值形影不离的一对区间值&#xff0c; 就是大名鼎鼎的置信区间了。 这置信区间和P值是怎么得来的&#xff0c;我想大多数盆友都不会有什么直观的概念&#xff0c;只会注意P值是否小于0.05或者0.01(根据显著性水平确定)。为了给大伙说清楚…