笔记-JavaWeb学习之旅
junit单元测试
- 黑盒测试:不需要写代码,给输入值,看程序是否能够输出期望的值
- 白盒测试:需要些代码,关注程序具体的执行流程
Junit使用: 白盒测试
步骤:
定义一个测试类(测试用例)
定义测试方法:可以独立运行
给方法加注解(@Test)(需要加上注解才可以独立运行方法)
导入Junit的依赖环境
判定结果:
红色:测试失败
绿色:测试成功
一般我们使用断言来处理结果Asser.assertEquals(期望的结果,实际结果);
补充:@Before:
修饰的方法会在测试方法之前被自动执行
@After:
修饰的方法会在测试方法执行之后被执行
package cn.itcast.junit;
//计算器类
public class Calculator {
public int add(int a,int b){
return a+b;
} public int sub(int a ,int b){
return a-b;
}
}package cn.itcast.test;
//需要导入junit包,才可以独立运行方法
import cn.itcast.junit.Calculator;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test; /**
* @Author: A
* @Date: 2019/5/30 10:33
* @Version 1.0
* 测试add方法
*/
public class CalculatorTest {
/*
* 初始化方法
* 用于资源申请,所有测试方法在执行之前都会先执行此方法
* */
@Before
public void init(){
System.out.println("init......");
}
/*
* 释放资源方法
* 在所有测试方法执行完毕后,都会执行该方法
* */
@After
public void close(){
System.out.println("close...");
}
@Test
public void testAdd(){
//System.out.println("我被执行了");
//创建计算器对象
Calculator c = new Calculator();
//调用add方法
int result = c.add(1,2);
System.out.println(result);
//断言
//我期望的结果是2,真实结果不是,断言失败
//程序控制台出现红色
Assert.assertEquals(3,result);
}
}
//init......
//3
//close...
反射:框架设计的灵魂
- 框架:半成品软件。可以在框架的基础上进行软件开发,简化代码
- 反射:将类的各个组成部分封装为其他对象,这就是反射机制(组成部分包括成员方法,成员变量,构造方法等)
- 反射:就是通过class文件对象,去使用该文件中的成员变量,构造方法,成员方法。
获取Class对象的方式:
- Class.forName("全类名"):将字节码文件加载进内存,返回Class对象
- 类名.class:通过类名的属性class获取
- 对象.getClass()
//Class.forName("全类名")
//多用于配置文件
Class cls1 = Class.forName("cn.itcast.domain.Person"); //类名.class
//多用于参数的传递
Class cls2 = Person.class; //对象.getClass()
//多用于对象的获取字节码的方式
Person p = new Person();
Class cls3 = p.getClass();
Field:成员变量
常用方法
1.设置值 void set (Object obj ,Object value)
2.获取值 get (Object obj)参数需要传递对象,
3.忽略访问权限修饰符的安全检查 setAccessible(true)
获取成员变量
package cn.itcast.reflect;
//接下来要写的几个获取功能的类都与此类有关联 public class Person {
private String name;
private int age;
public String a;
protected String b;
String c;
private String d; public Person() {
} public Person(String name, int age) {
this.name = name;
this.age = age;
} public String getName() {
return name;
} public int getAge() {
return age;
} public void setName(String name) {
this.name = name;
} public void setAge(int age) {
this.age = age;
} @Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", a='" + a + '\'' +
", b='" + b + '\'' +
", c='" + c + '\'' +
", d='" + d + '\'' +
'}';
}
public void eat(){
System.out.println("eat....");
}
public void eat(String food){
System.out.println("eat...."+food);
}
}
package cn.itcast.reflect; import java.lang.reflect.Field; public class ReflectDemo {
public static void main(String[] args) throws Exception{ //获取Person的Class对象
Class personClass = Person.class;
//调用Class对象的方法getFields获取成员变量,返回的是Field[] 成员变量的数组
//获取所有的public 修饰的成员变量
Field[] fields = personClass.getFields();
//对fields遍历,获取每一个public修饰的成员变量
for(Field field :fields){
System.out.println(field);
}
//获取指定名称的public 修饰的成员变量
//Field getField(String name)
Field a =personClass.getField("a");
//获取成员变量a的值,需要使用get(Object obj)方法,需要传递对象参数
Person p = new Person();
Object value = a.get(p);
System.out.println(value);//null
//设置成员变量a的值
a.set(p,"张三");
System.out.println(p);
System.out.println("====================");
//获取所有的成员变量,不考虑修饰符
Field[] declaredFields = personClass.getDeclaredFields();
for(Field dec :declaredFields){
System.out.println(dec);
}
//获取指定名称的成员变量
//Field getDeclaredField(String name)
Field d =personClass.getDeclaredField("d");
//忽略访问权限的修饰符的安全检查
d.setAccessible(true);
//获取成员变量的值,需要传递对象参数
Object value2 = d.get(p);
System.out.println(value2);
}
}
Constructor:构造方法
创建对象: T new Instance(Oject... initargs)参数是对象构造方法的参数类型
如果使用空参数构造方法创建对象,操作可以简化:Class对象的newInstance方法
获取构造方法
package cn.itcast.reflect; import java.io.ObjectStreamClass;
import java.lang.reflect.Constructor; public class ReflectDemo1 {
public static void main(String[] args) throws Exception{
//获取Person的Class对象
Class personclass = Person.class;
//获取Class对象的构造方fa
Constructor c =personclass.getConstructor(String.class,int.class);
System.out.println(c);
//构造方法用来创建对象的,
//Constructor 有个方法newInstance可以创建对象
Object person = c.newInstance("张三",22);
System.out.println(person); //使用空参数构造器创建对象
Constructor c1 =personclass.getConstructor();
System.out.println(c1);
Object person1 = c1.newInstance();
System.out.println(person1);
//可以通过Class对象方法直接创建空参数的构造器
Object o = personclass.newInstance();
System.out.println(o);
}
}
获取成员方法与类
Method:方法对象
执行方法:Object invoke(Object obj,Object...args) 需要传递真实的对象与参数列表
获取类名:
String getName()
package cn.itcast.reflect; import java.lang.reflect.Method; public class ReflectDemo2 {
public static void main(String[] args) throws Exception{
//获取Person的Class对象,返回的是一个Class类
Class personClass = Person.class;
//获取指定的Public成员方法
//需要传递方法的名称,返回值是Method类
Method eat_Method =personClass.getMethod("eat");
Person p = new Person();
eat_Method.invoke(p);//eat....
//获取有参数的成员方法,需要传递方法名称
Method eat_method2 =personClass.getMethod("eat",String.class);
//获取到方法,就要执行方法
//执行方法,需要传递对象和参数
eat_method2.invoke(p,"饭"); //获取所有public 方法
Method[] allMethod = personClass.getMethods();
for(Method method : allMethod){
//获取方法的名称getName();
System.out.println(method.getName());
System.out.println(method);
} //获取类名
String className=personClass.getName();
System.out.println(className);//cn.itcast.reflect.Person
}
}
案例
需求:写一个框架,不能改变给类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中任意的方法
步骤:
- 将需要创建的对象的全类名和需要执行的方法定义在配置文件中
- 在程序中加载读取配置文件
- 使用反射技术来加载类文件进内存
- 创建对象
- 执行方法
package cn.itcast.reflect; import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties; public class ReflectTest {
public static void main(String[] args) throws Exception{
//加载配置文件
//创建Properties对象
Properties pro = new Properties();
//获得Class字节码文件
Class c = ReflectTest.class;
//通过字节码文件c下的方法getClassLoader 可以获得一个类加载器
ClassLoader cl = c.getClassLoader();
//可以通过Classloader类下的方法“getResourceAsStream(String name)”可以找到需要的配置文件获得一个字节输入流
//传递的参数为要加载的文件,获取字节输入流
InputStream is= cl.getResourceAsStream("pro1.properties");
//Properties 类的方法 “load(InputStream inStream);”需要一个字节输入流的参数
//可以使用Properties集合中的方法load,把硬盘中保存的文件,读取到集合中使用
pro.load(is);//配置文件加载完成 //获取配置文件中定义的数据
String className = pro.getProperty("className");
String methodName=pro.getProperty("methodName"); //加载该类进内存,
Class cls= Class.forName(className);
//创建对象,可以通过Class中的方法newInstance来获取
Object obj= cls.newInstance();
//获取指定的成员方法
Method method = cls.getMethod(methodName);
//执行方法,需要传递对象obj
method.invoke(obj);
}
}
//似懂非懂……懂非懂…………非懂………………懂…………
注解
定义:注解(Annotation),也叫元数据,一种代码级别的说明,他是JDK1.5及以后版本引入的一个特性,与类,接口枚举是在同一个层次,他可以声明在包,类,字段,方法,局部变量,方法参数等的前面,用来对这些元素进行说明,注释
作用分类:
- 编写文档:通过代码里标识符的注解生产文档
- 代码分析:通过代码里标识的注解对代码进行分析
- 编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查
JDK中预定的一些注解
@Override :检测被该注解标注的方法是否是继承自父类的
@Deprecated: 该注解标注的内容,表示已过世
@SuppressWarnings:压制警告
自定义注解
格式:
元注解:
public @interface 注解名称{}
本质:注解本质上就是一个接口,该接口默认继承Annotation接口
属性:接口中可以定义成员方法
属性的返回值类型
1.基本数据类 2.String 3.枚举 4.注解 5.以上类型的数组
定义了属性,在使用时要给属性赋值
1. 如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不就行属性的赋值
- 如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可
3. 数组赋值时,值使用{}包裹,如果数组中只有一个值则{}省略
- 如果只有一个属性需要赋值,并且属性的名称是value,则value可以省略,直接定义值即可
元注解:用于描述注解的注解
@Target:描述注解能够作用的位置
ElementType取值:TYPE:可以作用于类上; METHOD:可以作用于方法上 FIELD:可以作用于成员变量上
@Retention: 描述注解能被保留的阶段
@Retention(RetentionPolicy,RUNTIME):当前被描述的注解,会保留到class字节码文件中,并被JVM读取到
@Documented:描述注解是否被抽取到api文档中
@Inherited:描述注解是否被子类继承
package cn.itcast.reflect;
public @interface Myanno2 {
}package cn.itcast.reflect;
//枚举类的定义
public enum Person2 {
p1,p2;
}package cn.itcast.reflect; public @interface Myanno {
//注解可以返回的类型
// 1.基本数据类 2.String 3.枚举 4.注解 5.以上类型的数组
int show1();
public abstract String show2() default "张三";
public abstract Person2 per();
Myanno2 anno2();
//String[] strs();*/ }package cn.itcast.reflect;
//String类型的返回值已经被default修饰了,可以不用对属性进行赋值
@Myanno(show1=1,per=Person2.p1,anno2=@Myanno2)
public class Worker {
}注解案例练习
package cn.itcast.reflect; 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.METHOD)
public @interface Check {
}package cn.itcast.reflect; public class Calculator {
//加法
@Check
public void add(){
System.out.println("1+0="+(1+0));
}
//减法
@Check
public void sub(){
System.out.println("1-0="+(1-0));
}
//乘法
@Check
public void mul(){
System.out.println("1*0="+(1*0));
}
//除法
@Check
public void div(){
System.out.println("1/0="+(1/0));
}
public void show(){
System.out.println("永无bug");
}
}package cn.itcast.reflect; import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method; /**
* 简单的测试框架
* 当主方法执行后,会自动检测所有方法(加了Check注解的方法)
*/ public class TestCheck {
public static void main(String[] args) throws IOException {
//创建计算器对象
Calculator c = new Calculator();
//获取字节码文件
Class cls = c.getClass();
//获取所有方法
Method[] methods = cls.getMethods();
int number =0;//出现异常的次数
BufferedWriter bw = new BufferedWriter(new FileWriter("bug.txt")); for(Method method : methods){
//判断方法上是否有Check注解
if(method.isAnnotationPresent(Check.class)){
//有,执行
try{
method.invoke(c);
}catch (Exception e){
//捕获异常
//记录到文件中
number++;
bw.write("方法出异常了");
bw.newLine();
bw.write("异常名称:"+e.getCause());
bw.newLine();
bw.write("异常的原因"+e.getCause().getMessage());
bw.newLine();
bw.write("--------------------");
bw.newLine();
}
bw.write("本次测试一共出现"+number+"次异常");
bw.flush();
}
}
}
}
/*
*本次测试一共出现0次异常本次测试一共出现0次异常方法出异常了
异常名称:java.lang.ArithmeticException: / by zero
异常的原因/ by zero
--------------------
本次测试一共出现1次异常本次测试一共出现1次异常
/
笔记-JavaWeb学习之旅的更多相关文章
- 笔记-JavaWeb学习之旅5
CP30的演示 package cn.itcast.datasourcejdbc; import com.mchange.v2.c3p0.ComboPooledDataSource; import j ...
- 笔记-JavaWeb学习之旅7
JavaScript基础 概念:一门客户端脚本语言,运行在客户端浏览器中,每一个浏览器都有JavaScript的解析引擎,是一个脚本语言,不需要编译,直接就可以被浏览器解析执行. JavaScript ...
- 笔记-JavaWeb学习之旅19
Redis:redis是一款高性能的NOSQL系列的非关系型数据库 NOSQL: Not Only SQL ,意即"不仅仅是SQL",是一项全新的数据库理念,泛指非关系型数据库 r ...
- 笔记-JavaWeb学习之旅18
AJAX:ASynchronous JavaScript And XML 异步的JavaScript 和XML 异步和同步:客户端和服务器端相互通信的基础上 同步:客户端操作后必须等待服务器端的响应, ...
- 笔记-JavaWeb学习之旅17
1.过滤选择器 首元素选择器:first 获得选择的元素中的第一个元素 尾元素选择器:last获得选择元素中的最后一个元素 非元素选择器:not(selector) 不包括指定内容的元素 偶数选择器: ...
- 笔记-JavaWeb学习之旅16
增强对象的功能 动态代理:在内存中形成代理类 实现步骤: 代理对象和真实对象实现相同的接口 代理对象 = Proxy.newProxyInstance(); 使用代理对象调用真实对象的方法 增强方法 ...
- 笔记-JavaWeb学习之旅15
Filter:过滤器 概念:当访问服务器的资源是,过滤器可以将请求拦截下来,完成一些特殊的功能 快速入门: 步骤: 定义一个类,实现接口Filter 复写方法 配置拦截路径 package com.d ...
- 笔记-JavaWeb学习之旅14
JSTL:JavaServer Pages Tag Library JSP标准标签库 if标签 <%@ page import="java.util.ArrayList" % ...
- 笔记-JavaWeb学习之旅10
Servlet server applet运行在服务器端的小程序,servlet就是一个接口,定义了Java类被浏览器访问到的规则(Java类重写这个接口,就可以被浏览器(tomcat)识别) Ser ...
- 笔记-JavaWeb学习之旅13
验证码案列 昨天晚上出现的500错误原因在于验证码没有获取到,获取验证码是应该获取的是共享域中的验证码,而我把获取值得键给写成了jsp中的键,而不是内存生成图片中,然后把图片上传到共享域中的键.这两个 ...
随机推荐
- 【转载】TCP的三次握手(建立连接)和四次挥手(关闭连接)
建立连接: 理解:窗口和滑动窗口TCP的流量控制 TCP使用窗口机制进行流量控制 什么是窗口? 连接建立时,各端分配一块缓冲区用来存储接收的数据,并将缓冲区的尺寸发送给另一端 接收方发送的确认信息中包 ...
- cocos2d-x触摸事件优先级
CCTouchDispatcher是管理cocos2d-x中全部Touch事件派发的类, CCTouchDispatcher中包括了两个CCTouchHandler的列表, 分别存储Standa ...
- arm-linux交叉编译环境搭建
1.解压交叉编译工具链包 tar jxvf EABI-4.3.3_EmbedSky_20100610.tar.bz2 (笔者将交叉编译工具链包放在”/home ”目录下) 解压后会生成两个目录: [r ...
- error: expected '=', ',', ';', 'asm' or '__attribute__' before '{' token
头文件函数声明少了“:(分号)”
- stm32GPIO8种模式
stm32GPIO工作模式及用途 1.浮空输入GPIO_IN_FLOATING ——浮空输入,可以做KEY识别,RX1 2.带上拉输入GPIO_IPU——IO内部上拉电阻输入 ...
- 获取IOS应用安装列表
原文转载至 http://blog.csdn.net/justinjing0612/article/details/8887747 转自鸟哥博客:http://blog.cnrainbird.com/ ...
- 【POJ 1159】Palindrome
[POJ 1159]Palindrome 近期各种题各种奇葩思路已经司空见惯了...又新出个滚动数组= = 该题另一点须要知道 最少须要补充的字母数 = 原序列S的长度 - S和S'的最长公共子串长度 ...
- 常见的页面效果,相关的js代码
1.焦点图 $(document).ready(function(){ var i=0; var autoChange= setInterval(function(){ if(i<$(" ...
- TTL以及LVDS接口传输【转】
本文转载自:http://blog.csdn.net/jscese/article/details/16860833 TTL接口:属于并行方式传输数据的接口,采用这种接口时,不必在液晶显示器的驱动板端 ...
- HDU3567 Eight II —— IDA*算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3567 Eight II Time Limit: 4000/2000 MS (Java/Others) ...