您的位置:首页 > 编程语言 > Java开发

Java进阶学习第七天——泛型与反射回顾

2016-04-18 23:26 363 查看

文档版本开发工具测试平台工程名字日期作者备注
V1.02016.04.18lutianfeinone

文档版本
开发工具
测试平台
工程名字
日期
作者
备注

V10

20160418
lutianfei
none

MyEclipse 的 DeBug调试模式

Junit单元测试

MyEclipse的快捷键

泛型

自定义泛形泛型方法

枚举类
枚举类特性

反射

Class类

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);
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: