文档版本 | 开发工具 | 测试平台 | 工程名字 | 日期 | 作者 | 备注 |
---|---|---|---|---|---|---|
V1.0 | 2016.04.18 | lutianfei | none |
MyEclipse 的 DeBug调试模式
- 跟踪程序的运行状态。
- 方便查看程序的源代码。
- 断点调试
- F5(跳入)
- StepOver F6(跳过)
- F7(跳出)
- Resume(跳到下一个断点,如果没有,程序执行完成)
- Drop to frame:回到方法的最顶端
- 移除所有断点,选择Debug模式,第二项,移除所有断点。
Junit单元测试
- 单元:类中的一个方法就是一个单元。
- 版本:JUnit3.x JUnit4.x(使用)
需要引入Junit的jar包,MyEclipse已经集成了,直接引入即可。
- 先写
@Test
然后右键选择Add JUnit 4 Library to the build path
- 先写
测试方法:
- 必须是public void demo(){ }
- 方法名在3.x版本是必须是testXxx,在4.x版本中方法名可以任意
- 不能有任何的参数
- 可以直接在某个方法前面加
@Test
点击对应的方法或类右键Run As Junit Test进行测试
注解:
@Test
(测试)@Innore
(忽略)@Before
(每个方法之前)@After
(每个方法之后)@BeforeClass
(在类之前,方法是静态方法)@AfterClass
(在类之后,方法是静态方法)
断言: Assert类
- Assert.assertEquals可以判断结果与期望值是否相同(了解),例如计算两个数的和。
@Test
属性@Test(timeout=100)
在100毫秒内执行完该程序,才算成功。
package cn.itcast.JUnitTest;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
public class JUnitTest {
@org.junit.BeforeClass
public static void beforeClass(){
System.out.println("BeforeClass...");
}
@Before
public void before(){
System.out.println("before...");
}
@Test
public void eat(){
System.out.println("eat...");
}
@Test
public void run(){
System.out.println("run...");
}
@After
public void after(){
System.out.println("after");
}
@AfterClass
public static void afterClass(){
System.out.println("afterClass");
}
}
MyEclipse的快捷键
Alt
+/
代码引导Ctrl
+T
在方法上按此键可进入实现类Ctrl
+鼠标左键
在方法上按此键可进入接口Ctrl
+Alt
+H
在方法上按此键可进入调用此方法的上一级方法Ctrl
+O
显示当前类中所有方法的列表Ctrl
+Shift
+O
导入缺少的包Ctrl
+Shift
+R
根据文件名搜索文件Ctrl
+Shift
+I
进入断点在参数上按此键显示具体内容Ctrl
+H
根据内容搜索文件Ctrl
+F
根据内容搜索当前文件Ctrl
+K
根据内容向下搜索当前文件Ctrl
+Shift
+K
根据内容向上搜索当前文件Ctrl
+Alt
+上或下
复制选中文本Alt
+上或下
移动选中文本Ctrl
+Alt
+/
拼写自动补全Ctrl
+Shift
+F
格式化文本F6
断点单步运行F8
按一次执行一个断点
泛型
- 泛型擦除:泛型存在源代码的阶段,编译成class文件后,泛型信息被擦除。
用到哪些集合?
- List
- Set
- Map
泛形的基本术语
- 以
ArrayList<E>
为例:<>
念typeof ArrayList<E>
中的E称为类型参数变量ArrayList<Integer>
中的Integer称为实际类型参数- 整个
ArrayList<Integer>
称为参数化类型ParameterizedType
- 以
JDK5以前,对象保存到集合中就会失去其特性,取出时通常要程序员手工进行类型的强制转换,这样不可避免就会引发程序的一些安全性问题。例如:
ArrayList list = new ArrayList();
list.add("abc");
Integer num = (Integer) list.get(0); //运行时会出错,但编码时发现不了
list.add(new Random());
list.add(new ArrayList());
for(int i=0;i<list.size();i++){
(?)list.get(i); //此处取出来的对象应转换成什么类型
}
自定义泛形——泛型方法
Java程序中的普通方法、构造方法和静态方法中都可以使用泛型。方法使用泛形前,必须对泛形进行声明,语法:
<T>
,T可以是任意字母,但通常必须要大写。<T>
通常需放在方法的返回值声明之前。例如:public static <T> void doxx(T t);
练习:
- 编写一个泛形方法,实现指定位置上数组元素的交换。
/**
* 测试
*/
@Test
public void run1(){
Integer [] arr = new Integer[]{1,2,3,4,5,6,7};
change(arr,1,3);
System.out.println(Arrays.toString(arr));
String [] strarr = new String[]{"aa","bb","cc","dd","ee","ff"};
change(strarr,1,3);
System.out.println(Arrays.toString(strarr));
}
/**
* 自定义泛型方法
* * 声明泛型 <T> 放在返回值之前
*/
public <T> void change(T[] arr, int idx1, int idx2){
T temp = arr[idx1];
arr[idx1] = arr[idx2];
arr[idx2] = temp;
}
- 注意:
- 方法的逻辑只与类型有关,这类方法可以定义成泛型方法。
- 只有对象类型才能作为泛型方法的实际参数。
- 在泛型中可以同时有多个类型,例如:
枚举类
- 为什么需要枚举?
- 一些方法在运行时,它需要的数据不能是任意的,而必须是一定范围内的值,此类问题在JDK5以前采用自定义带有枚举功能的类解决,Java5以后可以直接使用枚举予以解决
- JDK 5新增的
enum
关键字用于定义一个枚举类 - 创建枚举格式:
enum 枚举类型名称 {
枚举对象1名称,
枚举对象2名称,
… ,
枚举对象n名称;
}
枚举类特性
- 枚举类也是一种特殊形式的Java类。
- 枚举类中声明的每一个枚举值代表枚举类的一个实例对象。
- 与java中的普通类一样,在声明枚举类时,也可以声明属性、方法和构造函数,但枚举类的构造函数必须为私有的(这点不难理解)。
- 枚举类也可以实现接口、或继承抽象类。
- JDK5中扩展了swith语句,它除了可以接收int, byte, char, short外,还可以接收一个枚举类型。
若枚举类只有一个枚举值,则可以当作单态设计模式使用。
把构造方法放在枚举值的下面。
如果枚举的构造方法有参数,那么实例中必须有传入参数。
枚举的API
- Java中声明的枚举类,均是java.lang.Enum类的孩子,它继承了Enum类的所有方法。常用方法:
- name() 返回枚举对象名称
- ordinal() 返回枚举对象下标
- valueof(Class enumClass, String name) 转换枚举对象
- 自定义的枚举类 在编译阶段自动生成下面方法
- valueof(String name) 转换枚举对象(枚举对象调用)
- values() 获得所有枚举对象数组(枚举对象调用)
- 思考
- 枚举对象、枚举对象下标、枚举对象名称表示之间的转换
练习:
1.已知枚举对象,获取枚举的名称和下标。
2.已知枚举名称,获取枚举对象和下标。
3.已知枚举下标,获取枚举对象和名称。
package cn.itcast.enumtest;
import org.junit.Test;
/**
* 枚举的API
* @author Administrator
*
*/
public class Demo2 {
/**
* 1.已知枚举对象,获取枚举的名称和下标。
*/
@Test
public void run1(){
// 获取枚举对象
Love girl = Love.GIRL;
// 获取名称
System.out.println(girl.name());
// 获取下标值
System.out.println(girl.ordinal());
}
/**
* 2.已知枚举名称,获取枚举对象和下标。
*/
@Test
public void run2(){
String name = "READ";
// 获取枚举对象
Love read = Enum.valueOf(Love.class, name);
// 获取下标值
System.out.println(read.ordinal());
Love read2 = Love.valueOf(name);
System.out.println(read2.ordinal());
}
/**
* 3.已知枚举下标,获取枚举对象和名称。
*/
@Test
public void run3(){
int idx = 2;
Love[] loves = Love.values();
Love code = loves[idx];
System.out.println(code.name());
}
}
enum Love{
GIRL,READ,CODEING;
}
反射
- 什么是反射?
- 通过类的字节码文件可以获取类中的所有内容。
- 剖析Java类中的各个组成部分映射成一个个java对象
- 类 java.lang.Class
- java.lang.reflect
- 构造方法 Constructor
- 成员变量 Field
方法 Method
反射用在哪里
- 多用于框架和组件,写出复用性高的通用程序
Class类
Java中
java.lang.Class类
用于表示一个类的字节码(.class)文件如何得到某个class文件对应的Class对象
Class.forName(“包名.类名”)
Class类
代表某个类的字节码
,并提供了加载字节码的方法:forName(“包名.类名”)
,forName
方法用于加载类字节码到内存中,并封装成一个Class对象
作业:
- DOM4J解析XML(web.xml配置文件 )
- 拿到cn.itcast.servlet.HelloServlet
- 通过反射Class对象获取HelloServlet类中的所有方法和内容
<web-app>
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>cn.itcast.servlet.HelloServlet</servlet-class>
</servlet>
</web-app>
public class HelloServlet {
public void run(){
System.out.println("正在跑...");
}
}
package cn.itcast.test;
import java.lang.reflect.Method;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import cn.itcast.servlet.HelloServlet;
/**
* 使用DOM4J解析myweb.xml,通过反射run方法执行
* @author Administrator
*
*/
public class Demo {
@Test
public void run() throws Exception{
// 解析myweb.xml
// 获取解析器
SAXReader reader = new SAXReader();
// 解析
Document document = reader.read("src/myweb.xml");
// 获取根节点
Element root = document.getRootElement();
// 获取servlet节点
Element servlet = root.element("servlet");
Element servletClass = servlet.element("servlet-class");
// 获取包名+类名的全路径
String path = servletClass.getText();
// 获取Class对象
Class clazz = Class.forName(path);
// 获取实例
HelloServlet hello = (HelloServlet) clazz.newInstance();
// 获取方法
Method m = clazz.getDeclaredMethod("run");
m.setAccessible(true);
m.invoke(hello);
}
}