最近打算从0开始学学大数据,目前的主业是Android开发,但是当年毕业之后其实是搞J2EE的,所以打算没事又来拓展一下后台的技能,扩宽一下自己的知识体系对于自己的未来也能够多一些可能,另外大数据的一些知识其实对于搞Android也是有一些技能补充的,每一项技术并不是单独存在的,或多或少都会有一些交集,接下来会踏踏实实的从0开始一步步来学习它。

Junit:

关于它应该对于搞Java的人再熟悉不过了,不过为了觉得比较扎实,这里再来复习复习。

测试分类:

  • 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值。

    也就是只关注输入和输出,中间的流程是看不到的,好像被黑布蒙住了一样。如搞Android测试的那些,大部分全是这种,各种手指点点点就可以了。
  • 白盒测试【较高端,对于有追求的测试人员就应该成为这类~~】:需要写代码的。关注程序具体的执行流程。

    也就是输入输出的同时,其中中间的转换流程也要关注。

那了解了上面的测试分类之后,对于Junit这种单元测试它是属于哪种呢?它是属于白盒测试的一种,那下面咱们来看一下它的使用:

使用步骤:

1. 定义一个测试类(测试用例)
  建议:
  测试类名:被测试的类名Test CalculatorTest
  包名:xxx.xxx.xx.test

2. 定义测试方法:可以独立运行
  建议:
  方法名:test测试的方法名 testAdd()
  返回值:void
  参数列表:空参

3. 给方法加@Test
4. 导入junit依赖环境

5、判定结果:
  红色:失败
  绿色:成功
  一般我们会使用断言操作来处理结果
  Assert.assertEquals(期望的结果,运算的结果);

由于比较简单,这里就不实践了。

@Before&@After:

@Before:
  修饰的方法会在测试方法之前被自动执行
@After:
  修饰的方法会在测试方法执行之后自动被执行

上面的简单使用一下,工具还是使用IntelliJ IDEA:

那如果运行失败了,这俩标注的代码还会运行么?试一下:

反射:框架设计的灵魂

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

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

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

下面来简单梳理一下整个Java代码在计算机中经历的三个阶段:

获取Class对象的方式:

  • Class.forName("全类名"):将字节码文件加载进内存,返回Class对象。
    多用于配置文件,将类名定义在配置文件中。读取文件,加载类。下面来看下代码:
    先定义一个类:

  • 类名.class:通过类名的属性class获取。多用于参数的传递,下面演示一下:
  • 对象.getClass():getClass()方法在Object类中定义着。

    多用于对象的获取字节码的方式。
    下面演示一下:

那下面来将这三种生成的Class对象做下等号比较,看是不是同一个对像:

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

Class对象功能:

  • 获取成员变量们:

    1、Field[] getFields() :获取所有public修饰的成员变量
    下面来演示一下:

    下面运行一下:

    居然一个都木有打印出来。。因为它只获取public修饰的成员变量,而咱们目前Person类中木有public修饰的成员变量:

    所以。。接下来咱们定义一下:

    再次运行:

    2、Field getField(String name) 获取指定名称的 public修饰的成员变量

    那光获取它有啥用呢?肯定得设置和获取值嘛,所以其使用规则:

    下面来使用一下:

    3、Field[] getDeclaredFields() 获取所有的成员变量,不考虑修饰符:

    4、Field getDeclaredField(String name) 获取指定名称的成员变量

    那既然私有的属性也能获取,那是不是私有的属性也能设置和读取呢?下面来试一下:

    此时就需要增加一句代码既可:

    其实像私有的成员方法、构造方法其要访问也需要忽略掉这个安全检查。

  • 获取构造方法们:

    Constructor<?>[] getConstructors()
    Constructor<T> getConstructor(类<?>... parameterTypes)

    Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
    Constructor<?>[] getDeclaredConstructors()

    下面来演示一下:

    而获取的构造方法之后,很明显是可以创建对象的嘛,所以其Constructor创建对象的方法如下:

    下面来试一下:

    那如果不带参数来构造呢?

    这种空参的方式可以用简化的方式,通过Class.newInstance()方法,如下:

  • 获取成员方法们:

    Method[] getMethods()
    Method getMethod(String name, 类<?>... parameterTypes)

    Method[] getDeclaredMethods()
    Method getDeclaredMethod(String name, 类<?>... parameterTypes)

    下面来演示一下,先给类中添加几个方法:

    下面通过反射来调用一下它:

    那有了Method如何来执行它呢?如下:

    好,下面来用一下:

    下面再来定一个带参数的方法:

    再来调用一下:

    接下来获取所有public修饰的方法:

  • 获取全类名:
    String getName()
    下面来演示一下:

小案例练习:

需求:写一个"框架",不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中任意方法。
实现:
  1. 配置文件
  2. 反射
步骤:

  • 将需要创建的对象的全类名和需要执行的方法定义在配置文件中。

  • 在程序中加载读取配置文件。
  • 使用反射技术来加载类文件进内存。
  • 创建对象。
  • 执行方法。

    编译运行:

    好,如果我们再新建一个类,然后里面定义一个方法,在不修改方法调用代码,只需要改配置既可进行指定方法的调用了,如下:

注解:

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

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

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

概念描述:

  • JDK1.5之后的新特性。
  • 说明程序的。
  • 使用注解:@注解名称。

作用分类:

  • 编写文档:通过代码里标识的注解生成文档【生成文档doc文档】。
  • 代码分析:通过代码里标识的注解对代码进行分析【使用反射,自定义注解主要是用于它】。
  • 编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查【Override】。

JDK中预定义的一些注解:

  • @Override :检测被该注解标注的方法是否是继承自父类(接口)的。

    如果修改方法名,则直接会报错:

    也就是它会对安全进行一个检查。

  • @Deprecated:该注解标注的内容,表示已过时
    这个见得比较多,不多说。
  • @SuppressWarnings:压制警告
    一般传递参数all @SuppressWarnings("all")

自定义注解:

格式:
  元注解
      public @interface 注解名称{
          属性列表;
      }

本质:
注解本质上就是一个接口,该接口默认继承Annotation接口,下面咱们定义一个:

其中元注解先不用定义,为了探究其本质,咱们反编译看一下:

属性:
接口中的抽象方法,它有如下要求:

  • 属性的返回值类型有下列取值:

    1、基本数据类型
    2、String

    3、枚举
    下面咱们先定义一个枚举:

    然后在注解中定义一个这样的属性:

    4、注解
    那咱们先定义一个其它注解:

    5、以上类型的数组

    除了以上列的类型,其它返回类型则会报错的,比如咱们新建一个类:

    然后返回这个类型:

  • 定义了属性,在使用时需要给属性赋值:

    1. 如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性的赋值。
    2. 如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可。
    3. 数组赋值时,值使用{}包裹。如果数组中只有一个值,则{}可以省略

下面咱们来使用一下咱们自定义的注解,为了方便这里只定义一个方法,其它的暂且先注释掉:

此时报错了:

这是因为还要指定show1这个属性,也就是我们在注解类中定义的方法其实在使用时是相当于一个属性来使用的,所以:

而既然是属性,那么平常咱们在定义注解时给方法就得以属性的形式来命名,这样会比较顺期自然,如下:

再定义一个属性:

另外咱们可以在定义属性时就给其定义默认值,那么咱们在使用注解时就不必一定得要显示给它主动赋值了,比如:

而如果咱们将属性名声明为value,则咱们在使用时就更加简单了,实际开源框架中也大量会用到这个特性,如下:

然而此时的value可以省略掉:

上面的这种写法,有一个前提:“如果只有一个属性需要赋值,并且属性的名称是value”,这点需要特别的注意!!下面再来看一下其它类型的赋值情况,如:

此时就需要这样来使用了:

接下来再来看一下注解类型:

使用:

接下来再看一下数组类型:

使用一下:

其中关于数组还有一个特点:“如果数组中只有一个值,则{}可以省略”,比较简单,这里就不演示了。

元注解:

用于描述注解的注解。咱们需要掌握的注解有如下:

  • @Target:描述注解能够作用的位置,其中ElementType取值:

    TYPE:可以作用于类上
    METHOD:可以作用于方法上
    FIELD:可以作用于成员变量上
    下面来试一下,先新建一个注解:

    而这个里面写啥呢?可以看一下Target注解的定义:

    所以咱们来定义下属性:

    该注解的作用范围为:

    所以咱们使用一下:

    接下来再多加几个作用域:

  • @Retention:描述注解被保留的阶段,@Retention(RetentionPolicy.RUNTIME):当前被描述的注解,会保留到class字节码文件中,并被JVM读取到。

    而有时候可能需要用这种@Retention(RetentionPolicy.SOURCE),也就是注解只在源码中存在,而在运行期就不可见了,像Android Butterknife框架。
  • @Documented:描述注解是否被抽取到api文档中。

  • @Inherited:描述注解是否被子类继承。

    然后咱们新建一个子类来继续Worker类:

    很明显在Teacher类上木有注解,但是由于Worker已经有了MyAnno3注解了,而该注解又声明为了@Inherited,则子类Teacher也会自动继承父类Worker的MyAnno3注解的。

在程序使用(解析)注解:

获取注解中定义的属性值

  • 获取注解定义的位置的对象 (Class,Method,Field)。
  • 获取指定的注解。
    getAnnotation(Class)
    //其实就是在内存中生成了一个该注解接口的子类实现对象

    public class ProImpl implements Pro{
    public String className(){
    return "cn.itcast.annotation.Demo1";
    }
    public String methodName(){
    return "show";
    }
    }

  • 调用注解中的抽象方法获取配置的属性值。

在上面反射的案例中是采用了配置文件来达到不修改代码就能创建任何类的对象,这次咱们就用注解来代替配置文件【在很多时候其注解都是用来代替配置文件而用的】,达到同样的功能,下面先来新建一个注解:

接下来咱们使用一下该注解,这里再定义两个类,用来进行类方法的声明达到动态生成实例的效果,如下:

那接下来就是解析注解,然后通过反射来达到实例化对象的效果呗,如下:

接着则根据注解对象调用里面的方法来获得相关的值,如下:

为啥能这样调用呢?这里就得理解了:

之后则直接用反射来调用就可以了,跟之前配置的方式一样了,如下:

接着再调用其它类的方法,则只要修改注解既可,如下:

案例:简单的测试框架

比如小明写好了一个自定义的计算器,然后想叫我们来测一下里面的方法,一个个方法来测比较麻烦,此时就可以借助于注解的思路,先新建一个注解:

然后在我们想要测试的方法中加上该注解,如下:

接下来则编写一个测试框架用来进行测试,其实比较简单,这里就直接贴出来了:

/**
* 简单的测试框架
* <p>
* 当主方法执行后,会自动自行被检测的所有方法(加了Check注解的方法),判断方法是否有异常,记录到文件中
*/
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(); int number = 0;//出现异常的次数
BufferedWriter bw = new BufferedWriter(new FileWriter("bug.txt")); for (Method method : methods) {
//4.判断方法上是否有Check注解
if (method.isAnnotationPresent(Check.class)) {
//5.有,执行
try {
method.invoke(c);
} catch (Exception e) {
//6.捕获异常 //记录到文件中
number++; 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("本次测试一共出现 " + number + " 次异常"); bw.flush();
bw.close(); } }

编译运行:

然后打开bug.txt瞅一眼:

接下来咱们再来制造一个异常,看能否被检测出来:

运行:

小结:

大数据JavaWeb之java基础巩固----Junit&反射&注解的更多相关文章

  1. 大数据学习之Linux基础01

    大数据学习之Linux基础 01:Linux简介 linux是一种自由和开放源代码的类UNIX操作系统.该操作系统的内核由林纳斯·托瓦兹 在1991年10月5日首次发布.,在加上用户空间的应用程序之后 ...

  2. Java基础13:反射与注解详解

    Java基础13:反射与注解详解 什么是反射? 反射(Reflection)是Java 程序开发语言的特征之一,它允许运行中的 Java 程序获取自身的信息,并且可以操作类或对象的内部属性. Orac ...

  3. 黑马程序猿————Java基础日常笔记---反射与正則表達式

    ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 黑马程序猿----Java基础日常笔记---反射与正則表達式 1.1反射 反射的理解和作用: 首 ...

  4. java基础解析系列(六)---注解原理及使用

    java基础解析系列(六)---注解原理及使用 java基础解析系列(一)---String.StringBuffer.StringBuilder java基础解析系列(二)---Integer缓存及 ...

  5. Java基础教程:反射基础

    Java基础教程:反射基础 引入反射 反射是什么 能够动态分析类能力的程序称为反射. 反射是一种很强大且复杂的机制. Class类 在程序运行期间,Java运行时系统始终为所有对象维护一个被称为运行时 ...

  6. 大数据学习笔记——Java篇之基础知识

    Java / 计算机基础知识整理 在进行知识梳理同时也是个人的第一篇技术博客之前,首先祝贺一下,经历了一年左右的学习,从完完全全的计算机小白,现在终于可以做一些产出了!可以说也是颇为感慨,个人认为,学 ...

  7. 为大数据软件准备JAVA、Python环境

    环境:SUSE 11 64位 安装JAVA JDK 1.确定版本.一般都是安装最新的JDK(Java SE Development Kit).个别软件和系统需要特定版本的JDK,根据实际需要下载. 2 ...

  8. 大数据学习笔记——Java篇之IO

    IO学习笔记整理 1. File类 1.1 File对象的三种创建方式: File对象是一个抽象的概念,只有被创建出来之后,文件或文件夹才会真正存在 注意:File对象想要创建成功,它的目录必须存在! ...

  9. 大数据学习笔记——Java篇之集合框架(ArrayList)

    Java集合框架学习笔记 1. Java集合框架中各接口或子类的继承以及实现关系图: 2. 数组和集合类的区别整理: 数组: 1. 长度是固定的 2. 既可以存放基本数据类型又可以存放引用数据类型 3 ...

随机推荐

  1. Java进程故障排查思路及步骤

    故障场景 Java进程出现问题,通常表现出如下现象: Web应用响应时间长/超时,甚至不响应 CPU使用率极高/低,频繁出现Full GC,甚至OutOfMemoryError 响应时间长.超时,甚至 ...

  2. JobStorage.Current property value has not been initialized. You must set it before using Hangfire Client or Server API.

    JobStorage.Current property value has not been initialized. You must set it before using Hangfire Cl ...

  3. 第2部分 Elasticsearch查询-请求体查询、排序

    一.请求体查询 请求体 search API, 之所以称之为请求体查询(Full-Body Search),因为大部分参数是通过http请求体而非查询字符串来传递的. 请求体查询:不仅可以处理自身的查 ...

  4. Linux 就该这么学 CH04 VIM编辑器和Shell命令脚本

    0 概述 1 Vim编辑器 在linux 中一切都是文件,而配置一个服务就是修改其配置文件的参数. vim 编辑器有三种模式:命令模式,末行模式和编辑模式. 命令模式:控制光标移动,对文件进行操作. ...

  5. Pycharm DataBase Navigator Plugins 使用

    Pycharm DataBase Navigator Plugins 使用 原文补充一点

  6. 构建C1000K的服务器(1) – 基础

    转自: http://www.ideawu.net/blog/archives/740.html 著名的 C10K 问题提出的时候, 正是 2001 年, 到如今 12 年后的 2013 年, C10 ...

  7. 007 SpringCloud 学习笔记3-----Eureka注册中心

    1.Eureka概述 (1)引子 网约车出现以前,人们出门叫车只能叫出租车.一些私家车想做出租却没有资格,被称为黑车.而很多人想要约车,但是无奈出租车太少,不方便.私家车很多却不敢拦,而且满大街的车, ...

  8. 026 SSM综合练习02--数据后台管理系统--数据库表创建及SSM环境搭建

    1.数据库准备 本项目我们Oracle数据库,Oracle 为每个项目创建单独user,oracle数据表存放在表空间下,每个用户有独立表空间. (1)采用数据库管理员账号:SYSTEM,再配合数据库 ...

  9. SQL Server 2019 中标量用户定义函数性能的改进

    在SQL Server中,我们通常使用用户定义的函数来编写SQL查询.UDF接受参数并将结果作为输出返回.我们可以在编程代码中使用这些UDF,并且可以快速编写查询.我们可以独立于任何其他编程代码来修改 ...

  10. STL源码剖析——序列式容器#4 Stack & Queue

    Stack stack是一种先进后出(First In Last Out,FILO)的数据结构,它只有一个出口,元素的新增.删除.最顶端访问都在该出口进行,没有其他位置和方法可以存取stack的元素. ...