Java进阶学习第七天——泛型与反射回顾
2016-04-18 23:26
363 查看
文档版本 | 开发工具 | 测试平台 | 工程名字 | 日期 | 作者 | 备注 |
---|---|---|---|---|---|---|
V1.0 | 2016.04.18 | lutianfei | none |
开发工具
测试平台
工程名字
日期
作者
备注
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); } }
相关文章推荐
- (java)从零开始之--装饰者设计模式
- 提高 MyEclipse 开发速度
- JAVA动态代理(jdk和cglib)
- 学习javacv入门示例1:图像的读取显示翻转处理
- springMVC+freeMarker表单验证
- java编译运行原理
- java内部类设计的作用详解
- 解决普通文件夹转化为Eclipse工程
- Java中的int与Integer对比
- 论Jdk1.7 HashMap实现
- Struts的配置问题
- Struts的意义
- 有关java并发程序同步概念的全部意义
- servlet跳转出错的一个可能
- java制作登陆窗口示例
- Java中String类总结
- Myeclipse工具栏快捷图标丢失后找回
- Struts2框架中OGNL表达式的学习
- 4.Java中获取当前目录的方法
- 关于java中bean拷贝的思考