0
点赞
收藏
分享

微信扫一扫

Javaweb学习笔记——(七)——————myexlipse基本使用、jdk5.0新特性及反射讲解

1.debug调试模式:

*使用这种模式,调试程序(看到程序运行停止在这一行)

-显示出来行号

-双击左边,出现一个圆点,表示设置了一个断点

*使用debug as方式,运行程序

-特使是否进入到调试界面,yes

-在断点那里,有一个绿色的条,表示程序停止在这一行,没有向下运行

*可以让程序向下执行:

-使用 step over 快捷键是 F6(单步执行)

-resume F8:表示调试结束,执行直接向下运行

**比如当前的断点之后还有断点,就会跳到下一个断点

**如果当前的断点后面没有断点,程序直接运行结束



*debug另外一个用途

**查看程序的源代码

**F5 step into:进入到方法

**F7 step return:返回



2.myeclipse的快捷键的使用

*代码提示 alt /

*快速导包 ctrl shift o

*单行注释 ctrl /

*去掉单行注释 ctrl /

*多行注释 ctrl shift /

*去掉多行注释 ctrl shift \

*删除行 ctrl d



3.junit的使用

*单元测试



*测试的对象是一个类中的方法



*junit不是Javase的一部分,想要使用导入jar包

**但是,在myeclipse中自带了junit的jar包



*首先junit版本 3.x,4.x

*单元测试方法时候,方法命名规则 public 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:在每个方法之后运行



**断言(了解)

- Assert.assertEquals("测试期望的值", "方法运行的实际的值");







JDK5.0新特性

jdk1.1、 1.2、 1.4、 5.0 (因为在1.4过后,增加了好多新特性,所以直接没有1.5,直接命名为5.0)



**泛型、 枚举、 静态导入、 自动拆装箱、 增强for循环、 可变参数

**反射



5.泛型的简介

*为什么要使用泛型?

-一般使用在集合上

**比如现在把一个字符串类型的值放入到集合里面,这个时候,这个值放入到集合之后,失去本身的类型,只能是object类型

这个时候,比如想要对这个值进行类型转换,很容易出现类型转换错误,可以通过泛型解决



*在集合上如何使用泛型

-常用集合 list set map

-泛型语法 集合<String> 集合名称 = new 集合<String>();



*在泛型里面写是一个对象,String 不能写基本的数据类型 比如int

**写基本的数据类型对应包装类

byte -- Byte

short -- Short

int -- Integer

long -- Long



float -- Float

double -- Double



char -- Character



boolean Boolean







*在list上使用泛型

List的三种实现方式:ArrayList linkedList Vector

代码

List<String> list = new ArrayList<String>();



list.add("aaa");

list.add("bbb");



// 比如吧aaa值取出来,类型转换,转换成int类型,会类型转换的错误。.



// 遍历list集合 有三种方式 三种

// 普通for循环,增强for,迭代器



// 普通for循环

for (int i = 0; i < list.size(); i++) {

String listStr = list.get(i);

System.out.println(listStr);

}



// 增强for

for (String listStr : list) {

System.out.println(listStr);

}



// 迭代器

Iterator<String> iterator = list.iterator();

while (iterator.hasNext()) {

System.out.println(iterator.next());

}



*在set上使用泛型

*代码

//泛型在set上的使用(唯一性,无序性)

public void testSet() {

Set<String> set = new HashSet<String>();

set.add("www");

set.add("aaa");

set.add("bbb");

set.add("zzz");

set.add("zzz");



//遍历set,有两种方式

//迭代器,增强for



//使用增强for遍历

for (String string : set) {

System.out.println(string);

}



//使用迭代器遍历

Iterator<String> iterator = set.iterator();

while(iterator.hasNext()){

System.out.println(iterator.next());

}



*在map上面使用泛型

-map结构:key-value形式

代码:

Map<String, String> map = new HashMap<String, String>();

map.put("001", "aaa");

map.put("002", "bbb");

map.put("003", "ccc");



//遍历map,有两种遍历方式

//1.获取所有的key,通过key来得到value,使用get方法

//2.获取key和value的关系



//使用第一种方式遍历

//获取所有的key

Set<String> sets = map.keySet();

//遍历所有的key返回的set

for (String key : sets) {

//通过得到的key得到value

String value = map.get(key);

System.out.println(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();

System.out.println(keyv+" "+valuev);

}.





6.泛型使用在方法上

*定义一个数组,实现指定位置上的数组元素的交换

*方法逻辑相同,只是数据类型不同,这个时候使用泛型方法

*
/*

* 使用泛型方法需要定义一个类型 使用大写字母表示T:这个T表示任意的类型 写在返回值之前 void之前 ========表示定义了一个类型

* 这个类型就是T 在下面就可以使用这个类型了

*/

public static <T> void swap1(T[] arr, int a, int b) {

T temp = arr[a];

arr[a] = arr[b];

arr[b] = temp;

}



7.泛型在类上的使用

*在一个类上定义了一个类型,这个类型可以在类里面直接使用

//在类里面就可以直接使用T类型

T aa;

public void test11(T bb){



}



//写一个静态方法,在类上定义的泛型,不能在静态方法中使用

public static void test22(T cc){



}



8.枚举的简介

*什么的枚举

**需要在一定范围内取值,这个值只能是这个范围内中的任意一个。

**现实场景:交通信号灯,有三种颜色,但是每次只能亮里面的任意一个



*使用一个关键字enum :

**代码:

enum Color3 {

RED, GREEN, YELLOW;

}

*枚举的构造方法也是私有的



*特殊枚举的操作

**在枚举类里面有构造方法

**构造方法里面有参数,需要在每个实例上面都写参数

**在枚举类里面有抽象方法

**在枚举的每一个实例里面都重写这个抽象方法





9.枚举的api的操作

**
name():返回枚举的名称

**
ordinal():枚举的下标

**
valueOf(Class<T> enumType, String name):得到枚举的对象



**
还有两个方法,这个两个方法不在api 里面,编译的时候生成两个方法

***valueOf(String name)
转换枚举对象

***values() 获取所有的枚举对象数组



*练习:

1.// 知道枚举的对象,得到枚举的名称和下标

@Test

public void test1() {

// 得到枚举对象

Color100 c100 = Color100.RED;

// 枚举名称

String name = c100.name();

// 枚举下标

int idx = c100.ordinal();

System.out.println(name + " " + idx);

}



2.// 知道枚举的名称,得到枚举的对象和下标

@Test

public void test2() {

String name1 = "GREEN";

// 得到对象

Color100 c1 = Color100.valueOf(name1);

// 枚举下标

int idx1 = c1.ordinal();

System.out.println(idx1);

}



3.// 知道枚举的下标,得到枚举的对象和名称

@Test

public void test3() {

int idx2 = 2;

// 得到枚举的对象

Color100[] cs = Color100.values();

// 根据下标得到对象

Color100 c12 = cs[idx2];

// 得到枚举的名称

String name = c12.name();

System.out.println(name);

}





10.静态导入

*可以再代码里面,直接使用静态导入方式,导入静态方法或者常量

*import static XX.XX.xxx



*import static java.lang.System.out;

*import static java.util.Arrays.sort;



**比如实现一个计算器 在Math类里面





11.自动拆装箱

*装箱:

**把基本的数据类型转换成包装类

*拆箱:

**把包装类转换成基本的数据类型



**
//自动装箱

Integer i = 10;



//自动拆箱

int m = i;



**在jdk1.4里面如何实现装箱和拆箱

//在jdk1.4里面实现拆装箱

private void test() {

//装箱

Integer i = new Integer(10);



//拆箱

int i2 = i.intValue();

}



**jdk是向下兼容

比如子jdk1.4里面写的代码,到5.0里面也可以运行



练习:

==执行的结果会调用 doSomething(double d)

==首先在jdk1.4里面是调用这个方法,如果需要调用doSomething(Integer i)这个方法,则需要类型转换,但是jdk1.4不能实现自动拆装箱

==由于jdk是向下兼容的,所以,在jdk1.4调用这个方法,在jdk5.0还是会调用相同的方法

public static void main(String[] args) {

doSomething(1);

}





public static void doSomething(double d) {

System.out.println(1.0);

}




public static void doSomething(Integer i) {

System.out.println(1);

}





** 八种基本的数据类型对应的包装类

*int -- Integer

*char -- Character



12.增强for循环

*语法:for(遍历出来的值 : 要遍历的集合) {}

for (String string : list) {

System.out.println(string);

}

*实现Iterable接口可以使用增强for循环



*在集合上使用增强for循环遍历

list set 实现了Iterator接口,所以可以使用增强for循环

map不能使用增强for循环,没有实现Iterator接口,所以不能使用只增强for循环



*增强for循环出现目的:为了替代迭代器

**增强for底层就是迭代器



13.内容补充

(1).泛型擦除

*首先泛型知识出现在源代码阶段,当编译之后泛型就不存在了



(2).练习:实现一个泛型方法,接受任意类型元素,颠倒数组

*代码:

private static <T> void reverses2(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;

}

}



14.可变参数(指数量上的可变)

*可变参数应用场景:

**实现两个数的相加,实现三个数的相加,实现四个数的相加...



--如果实现的多个方法,这些方法里面逻辑基本相同,唯一不同的是传递的参数的个数,可以使用可变参数

*可变参数的定义方法 数据类型...数组的名称

*理解为一个数组, 这个数组存储传递过来的参数

-代码

public static void add1(int...nums){

//nums可以理解一个数组,用于存储传递过来的参数

//System.out.println(nums.length);



//遍历数组

int sum = 0;

for (int i = 0; i < nums.length; i++) {

sum += nums[i];

}



System.out.println(sum);

}



*注意的地方

(1)可变参数需要写在方法的参数列表中,不能单独定义

(2)在方法的参数列表中只能有一个可变参数

(3)方法的参数列表中的可变参数,必须放在参数的列表之后

-add(int a, int...nums)



15.反射的原理

*应用在一些通用性比较高的代码中

*在后期中的框架中,大多数都是使用反射来实现的



*在框架开发中,都是基于配置文件开发

**在配置文件中配置了类,可以通过反射得到类中的所有内容,可以让类中的某个方法来执行



*类中的所有内容:属性、没有参数的构造方法,有参数的构造方法、普通方法



**反射的原理:

*首先需要把java文件保存到本地硬盘 .java

*编译java文件,成 .class文件

*使用jvm,把class文件通过类加载加载到内存中

*万事万物皆对象,class文件到内存中使用Class类表示



*当使用反射时候,首先需要获取到Class类,得到这个类之后,就可以得到clss文件里面的所有内容了

-包含属性 构造方法
普通方法

*属性通过一个类:Filed

*构造方法通过一个类:Constructor

*普通方法通过一个类:Method



16.使用反射操作类里面的无参数的构造方法

*首先获取到Class类

// 获取class类

Class class1 = Person.class;

Class class2 = new Person().getClass();

Class class3 = Class.forName("com.changeyd.test09.Person");

*比如:对一个类型进行实例化,可以new,如果不使用new,如何获取?

//得到class类

Class class1 = Class.forName("com.changeyd.test09.Person");

//得到Person类的实例

Person person = (Person) class1.newInstance();

-代码:

//操作无参数的构造方法

@Test

public void test1() throws ClassNotFoundException, InstantiationException, IllegalAccessException{

//得到class类

Class class1 = Class.forName("com.changeyd.test09.Person");

//得到Person类的实例

Person person = (Person) class1.newInstance();

//设置值

person.setName("Wangji");

System.out.println(person.getName());

}



17.使用反射操作有参数的构造方法

//操作有参数的构造方法

@Test

public void test2() throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException,

IllegalAccessException, IllegalArgumentException, InvocationTargetException {

// 得到class类

Class class1 = Class.forName("com.changeyd.test09.Person");

// 使用有参数的构造方法

// class1.getConstructors();//获取所有的构造方法

Constructor cs = class1.getConstructor(String.class, String.class);

// 通过有参数的构造方法设置值

// 通过有参数的构造方法来创建Person实例

Person person = (Person) cs.newInstance("lisi", "100");

System.out.println(person.getId() + " " + person.getName());



}



18.使用反射来操作属性

*
@Test

public void test3() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException,

SecurityException, InstantiationException {

try {

// 得到class类

Class class1 = Class.forName("com.changeyd.test09.Person");



// 得到name属性

// class1.getDeclaredFields();//表示得到所有的属性

// 得到Person类的实例

Person person = (Person) class1.newInstance();

//通过这个方法得到属性,参数是属性的名称

Field field = class1.getDeclaredField("name");



//操作的是私有的属性,不让操作,需要设置可以操作私有属性setAccessible(true),可以操作私有属性

field.setAccessible(true);



// 设置name值 set方法,两个参数:第一个参数类的实例,第二个参数是设置的值

field.set(person, "wangwu");// 相当于在p.name = "wangwu";

System.out.println(field.get(person)); // 相当于p.name;



} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}





19.使用泛型来操作普通方法

*使用Method来表示普通方法

*代码

// 普通方法,比如操作 setName

@Test

public void test4() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException,

NoSuchMethodException, SecurityException, InstantiationException, ClassNotFoundException {

// 得到Class类

Class class1 = Class.forName("com.changeyd.test09.Person");

// 得到Person的实例

Person person = (Person) class1.newInstance();

// 得到普通方法

// class1.getDeclaredFields();//得到所有的普通方法

//传递两个参数:第一个参数,方法名称;第二个参数,通过方法设置的值

Method method = class1.getDeclaredMethod("setName", String.class);

// 让setName方法执行,执行设置值

//使用invoke(person, "niuqi");传递两个参数;第一个参数,person实例;第二个参数,设置的值

//执行了invoke方法之后,相当于,执行了setName方法,同事通过这个方法设置了一个值是niuqi。

method.invoke(person, "niuqi");



System.out.println(person.getName());

}



//如果操作的是私有的方法,需要设置值为true

method.setAccessible(true);



*当操作的方法是静态的方法时候,因为静态方法调用的方式是 类名.方法名,不需要类的实例

*使用反射操作静态方法的时候,也是不需要实例

*在invoke方法的第一个参数里面,写一个null

-method.invoke(null, "wangji");

举报

相关推荐

0 条评论