junit的使用
*单元测试
*测试对象是一个类中的方法
*junit不是javase的一部分,想要使用需要导入jar包,myeclipse,eclipse自带
*junit的版本 3.x 4.x
*单元测试方法命名规则:publi void 方法名(){}
*使用注解方式运行测试方法
** @Test:表示方法进行单元测试
---@Test
public void testAdd1(){
TestJunit test01 = new TestJunit();//实例化要测试的类
test01.testAdd(2,3);//调用方法
}
-双击选中方法名称,右键选择run as - junit test
-当出现绿色条,表示方法测试通过
-当出现红棕色条,表示方法测试不通过
要运行多个测试方法,点击类中的其他位置(比如类声明后面)右键选择run as - junit test
** @Ignore:表示方法不进行单元测试
** @Before:在每一个方法执行前运行
** @After:在每一个方法执行后运行
jdk5.0新特性
**泛型、枚举、静态导入、自动拆装箱、增强for循环、可变参数
**反射
1.泛型的简介
*为什么要使用泛型?
---一般使用在集合上
**比如现在把一个字符串类型的值放入到集合里面,这个时候,这个值放入到集合后,会失去本来的类型编程object类,这个时候想要对这个值进行类型转换,很容易出现类型转换错误
*在集合上如何使用泛型
-常用集合 list set map
-泛型语法 集合<String> 例如 List<String>
*泛型里面是一个对象,不能写基本数据类型 比如int
**写基本的数据类型对应的包装类
byte -- Byte
short -- Short
int -- Integer
long -- Long
float -- Float
double -- Double
char -- Character
boolean -- Boolean
*在list上使用泛型
list的三种实现 ArrayList linkedList Vector
代码:
public void testList(){
List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
//遍历list集合有三种方式:普通for循环、迭代器、增强for
//普通for循环
for(int i = 0;i<list.size();i++){
String s = list.get(i);
syso(s);
}
syso(============);
//增强for循环
for(String s1 : list){
syso(s1);
}
//迭代器遍历
Iterator<String> it = list.iterator();
while(it.hasNext()){
syso(it.next());
}
}
*ArrayList linkedList Vector 这三个区别:
*在set上使用泛型
代码:
public void testSet(){
Set<String> set = new HashSet<String>();
set.add("www");
set.add("qqq");
set.add("zzz");
//遍历set有两种方式:迭代器,增强for
//使用增强for遍历
for(String s2 : set){
syso(s2);
}
//使用迭代器遍历
Iterator<String> it1 = set.iterator();
while(it1.hasNext()){
syso(it1.next());
}
}
*在map上面使用泛型
-map结构:key-value形式
代码:
public void testMap(){
Map(String,String) map = new HashMap<Srting,String>();
map.put("aaa","111");
map.put("bbb","222");
map.put("ccc","333");
//遍历map有两种方式:第一种是获取所有的key,通过key得到value,通过get方法
第二种是获取key和value的关系
//获取所有的key
Set<String> sets = map.keySet();
//遍历所有key返回的set
for(String key : sets){
//通过key得到value
String value = map.get(key);
syso(key+" : "+value);
}
//得到key和value的关系
Set<Entry<String,String>> sets1 = map.entrySet();
//遍历sets1
for(Entry<String,String> entry : sets1){
//entry是key和value的关系
String keyv = entry.getKey();
String valuev = entry.getValue();
syso(keyv+" : "+valuev);
}
}
泛型在方法上的使用
*定义一个数组,实现指定位置上数组元素的交换
*方法逻辑相同,植是数据类型不同,这个是时候使用泛型方法
*使用泛型方法 需要定义一个类型 使用大写字母表示 T:这个T表示任意的类型
*写在返回值之前 void之前<T>
*代码:
public static <T> void swap(T[] arr,int a,int b){
T temp =arr[a];
arr[a] = arr[b];
arr[b] = temp;
}
*/*/*/泛型在类上的使用
**在一个类上定义一个类型,这个类型可以在类里面直接使用
**public class TestDemo04<T>{
//在类里面可以直接使用T的类型
T aa;
public void test11(T bb){}
//写一个静态方法 在类上面定义的泛型,不能在静态方法里面使用
public static <A> void test12(A cc){}
}
枚举的简介
*使用关键字 enum
**enum Color3{
RED,GREEN,YELLOW;
}
*枚举构造方法也是私有的
*特殊枚举的操作
**在枚举类里面有构造方法
构造方法里面有参数,需要在每个实例上面都传递参数
**在枚举类里面有抽象方法
在枚举的每个实例里面都重写这个抽象方法
*枚举的api操作
**name() :返回枚举的名称
**ordinal() :枚举的下标,从0开始
**valueOf(Class<T> enumType,String name) :得到枚举的对象
**还有两个方法,但是这两个方法不在api里面,是编译时候生成的两个方法
***valueof(String name) :转换枚举对象
***values() :获得所有枚举对象数组
*练习:枚举对象,枚举对象下标,枚举对象名称表示之间的转换
//知道枚举的对象,得到枚举名称和下标
@Test
public void test1(){
//得到枚举对象
Color100 c100 = Color100.RED;
//枚举名称
String name = c100.name();
//枚举的下标
int idx = c100.ordinal();
System.out.println(name+" "+idx);
}
//知道枚举的名称,得到枚举对象和下标
@Test
public void test2(){
String name1 = "GREEN";
//得到对象
Color100 c1 = Color100.valueOf(name1);
//枚举下标
int idx1 = c1.ordinal();
}
//知道枚举下标,得到枚举的对象和名称
@Test
public void test3(){
int idx2 = 2;
//得到枚举的对象
Color100[] cs = Color100.values();
//根据下标得到对象
Color100 c12 = cs[idx2];
//得到名称
String name = c12.name();
syso(name);
}
静态导入(了解)
*可以在代码里面,直接使用静态导入方式,导入静态方法或者常量
*import static XX.XX.xxx
*import static java.lang.System.out;
*import static java.util.Arrays.sort;
**比如实现一个计算器,在Math类里面
自动拆装箱
*装箱
**把基本数据类型转换成包装类
*拆箱
**把包装类转换成基本的数据类型
** //自动装箱
Interger i = 10;
//自动拆箱
int m = i;
**在jdk1.4里面如何实现装箱和拆箱
//在jdk1.4里面实现拆装箱
public void test1(){
//装箱
Integer m = new Integer(10);
//拆箱
int a = m.intValue();
}
**jdk是会向下兼容的 :比如在jdk1.4写的代码,5.0也能运行
增强for循环
*语法for(遍历出来的值:要遍历的集合){}
*数组:实现Iterable接口的可以使用增强for循环
*在集合上使用增强for循环遍历
list set 实现了Iterator接口,所以可以使用增强for循环
map不能使用增强for,因为没有实现Iterator接口
*增强for循环出现的目的:为了替代迭代器
**增强for循环底层就是迭代器
内容补充
*泛型擦除
*首先泛型只是出现在源代码阶段,当编译之后泛型不存在了
*练习:实现一个泛型方法,接受任意类型的数组,颠倒数组中的所有元素
*代码:
public static <T> void reverses(T[] arr1){
/*
*基本思想:第一个跟最后一个交换位置,第二个跟倒数第二个狡猾
*交换 长度/2
*/
//遍历数组
for(int i = 0;i<arr1.length/2;i++){
//int temp = arr1[0];
//arr1[0] = arr1[arr1.length-1];
T temp= arr1[i];
arr1[i] = arr1[arr1.length-i-1];
arr1[arr1.length-i-1] = temp;
}
}
可变参数
*可变参数应用场景:
**实现两个数的相加,实现三个数的相加,四个数的相加
- -如果实现的多个方法,这些方法里面逻辑基本相同,唯一不同的是传递的参数的个数不同,可以使用可变参数
*可变参数的定义方法 数据类型...数组名称
*理解为一个数组,这个数组存储传递过来的参数
- 代码
public static void add1(int...nums){
//nums理解为一个数组,这个数组存储传递过来的参数
//System.out.println(nums.length);
int sum = 0;
//遍历数组
for(int i;i<nums.length;i++){
sum+=nums[i];
}
System.out.println(sum);
}
*注意的地方
- 可变参数需要写在方法的参数列表中,不能单独定义
- 在方法的参数列表中只能有一个可变参数
- 方法的参数列表中的可变参数,必须放在参数最后
-add1(int a,int...nums)
反射的原理(理解)
*应用在一些通用性比较高的代码中
*后面学到的框架,大多数都是使用反射来实现的
*在框架开发中,都是基于配置文件开发的
**在配置文件中配置了类,可以通过反射得到类中的所有内容,可以让类中的某个方法来执行
*类中的所有内容:属性,没有参数的构造方法,有参数的构造方法,普通方法
*画图分析反射原理
- 首先需要把java文件保存到本地硬盘 .java
- 编译java文件成.class文件
- 使用jvm把class文件通过类加载器加载到内存中
- 万事万物皆是对象,class文件在内存中使用Class类表示
- 当使用反射的时候,首先需要获取到Class类,得到这个类之后,就可以得到class文件里面的所有内容(属性,构造方法,普通方法)
- 属性通过一个类Filed
- 构造方法通过一个类Constructor
- 普通方法通过一个类Method
使用反射操作类里面的属性
*首先获取到class类
//获取Class类
Class c1 = Person.class;
Class c2 = new Person().getClass();
Class c3 = Class.forName("cn.itcast.test09.Person");
*比如,要对一个类进行实例化,可以new,那么不使用new,怎么获取?
//得到Class
Class c3 = Class.forName("cn.itcast.test09.Person");
//得到Person类的实例
Person p = (Person) c3.newInstance();
*代码
//操作无参数的构造方法
@Test
public void test1() throws Exception{
//得到Class
Class c3 = Class.forName("cn.itcast.test09.Person");
//得到Person的实例
Person p = (Person) c3.newInstance();
//设置值
p.setName("zhangsan");
System.out.println(p.getName());
}
使用反射操作有参数的构造方法
//操作有参数的构造方法
@Test
public void test2() throws Exception{
//得到Class
Class c1 = Class.forName(“cn.itcast.test09.Person”);
//使用有参数的构造方法
//c1.getConstructors();//获取所有的构造方法
//传递是由参数的构造方法里面参数类型,类型使用class形式传递
Constructor cs = c1.getConstructor(String.class,String.class);
//通过有参数的构造方法设置值
//通过有参数的构造方法创建Person实例
Person p1 = (Person) cs.newInstance(“lisi”,“100”);
System.out.println(p1.getId()+" "+p1.getName());
}
使用泛型操作普通方法
*使用Method类表示普通方法
*代码
//操作普通方法,比如操作setName
@Test
public void test4() thorws Exception{
//得到Class类
Class c4 = Class.forName("cn.itcast.test09.Person");
//得到Person实例
Person p4 = (Person) c4.newInstance();
//得到普通方法
//c4.getDeclaredMethods()//得到所有普通方法
//传递两个参数:第一个参数,方法名称;第二个参数。通过方法设置的值
Method m1 = c4.getDeclaredMethod("setName",String.class);
//让setName方法执行,执行设置值
//使用invoke(p4,"niuqi");传递两个参数:第一个参数,Person实例;第二个参数:设置的值
//执行了invoke方法之后,相当与执行了setName方法,同时通过这个方法设置了一个值是niuqi
m1.invoke(p4,"niuqi");
System.out.println(p4.getName());
}
//操作的私有方法,需要设置值是true
//m1.setAccessible(true);
*当操作的方法是静态方法时,因为静态方法调用方式是 类名.方法名 不需要类的实例
*使用反射操作静态方法时候,也是不需要实例的
*使用invoke方法的第一次参数写null
- m1.invoke(null,"niuqi");