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

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


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

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值