javaweb笔记(方立勋)
时间:2022-08-15 02:00:00
1.1 Eclipse的使用
工作空间目录是纯英语无空间的路径
在eclipse下Java编写和操作程序,以及java运行环境的配置。
新建java工程day01可配置在弹出窗口jre
工程右键属性可配置编辑器的版本
1.2 调试程序
1.3 Debug窗口
Resume(F8)下一个断点
Step into(F5)进入函数等
Step over(F6)下一行代码
Step return(F7)返回调用的下一行
Drop to Frame回到当前方法的第一行,
Terminate (F12)终止虚拟机,程序结束。(调试后使用)
右键watch观察变量的值
1.4 Breakpoints窗口
因此断点被移除
1.5 注意断点
1. 调整后,删除断点
2. 调整后,断点必须结束JVM。
2 03-eclipse常用快捷键
MyEclipse默认编码设置工作空间utf-8.使新建工程使用默认编码
菜单栏——Window / Preferences / General / Workspace 。
内容提示:Alt / Content Assist
选择多行代码,按Tab按钮向右推整块,按钮Shift Tab是整块向左缩进
快速修复:Ctrl 1
导包:Ctrl shift O
格式化代码块:ctrl shift F
向前向后:Alt 方向键(left right arrow)查看源代码时
添加注释 Ctrl Shift /
除去注释 Ctrl Shift \
查看源代码 Ctrl 单击 ctrl shift t
检查方法说明:F2
重置透视图 Window menu下
更改为大写 Ctrl Shift X
更改为小写 Ctrl Shift Y
复制行 Ctrl Alt 向下键(有些不能用)
检查继承关系Ctrl T
查看快捷键Ctrl shift L
3 04-junit测试框架
在Outline右键在窗口方法上Run As /JUnit Test 测试某种方法,类上右键run as /JUnit Test 测试这一类的所有方法
1、用junit单元测试时,必须在每种测试方法中添加@Test注解
2、用@Before注释是在每种测试方法之前执行的。
3、用@After注释是在每种测试方法后执行的。
4、用@BeforeClass 注释的静态方法是在所有方法被测试之前执行的方法,就像类中的结构方法一样。初始化一些需要使用的变量和其他资源。
5、用@AterClass注释的静态方法是在所有测试方法之后执行的。c 中析构函数。用于释放一些资源。
6.使用断言Assert可以判断被测方法的返回值是否与您预期的相同。
//person.java
package cn.itcast.elclipse;
public class Person {
public void eat()
{
System.out.println("eating.");
}
public String run()
{
System.out.println("runing.");
return "1";
}
} //demo4.java
package cn.itcast.elclipse;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class Demo4 {
@Before
public void before(){
System.out.println("before");
}
@Test
public void testRun()
{
Person p=new Person();
p.run();
}
@Test
public void testEat(){
Person p=new Person();
p.eat();
}
@After
public void after(){
System.out.println("after");
}
}
//Demo5.java
package cn.itcast.elclipse;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class Demo5 {
@BeforeClass
public void beforeClass(){
System.out.println("beforeclass");
}
@Test
public void testRun()
{
Person p=new Person();
p.run();
}
@Test
public void testEat(){
Person p=new Person();
p.eat();
}
@AfterClass
public void afterClass(){
System.out.println("afterclass");
}
} //Demo6.java
package cn.itcast.elclipse;
import junit.framework.Assert;
import org.junit.Test;
public class Demo6 {
@Test
public void testRun()
{
Person p=new Person();
Assert.assertEquals("2", p.run());
}
}
4 java5.静态导入和自动装箱拆卸.avi
JDK五中新增了许多新的java使用这些新语法可以帮助开发人员编写更高效、清晰、安全的代码。
静态导入 自动装箱/拆箱 增强for循环 可变参数 枚举反射内省 泛型 元数据
4.1 静态导入
JDK 1.5 增加的静态导入语法用于导入类的静态属性或方法。使用静态导入可以简化程序对类静态属性和方法的调用。
语法:
Import static 包名.类名.静态属性|静态方法|*
例如:
4.2 自动装箱/拆箱
JDK5.0语法允许开发人员直接将基本数据类型赋予相应的包装类变量, 或者赋给 Object 类型变量称为自动装箱。
自动拆箱与自动装箱相反,即将包装对象直接赋予相应的基本类型变量。
典型应用:
静态导入 自动装箱/拆箱
import static java.lang.System.out
import static java.lang.Math.*
//Demo1
package cn.itcast.demo;
import static java.lang.System.out;
import static java.util.Arrays.*;
public class Demo1 {
public static void main(String[] args) {
out.print("main");
int []a=new int[6,5,3};
sort(a);
for(int i:a)
out.print(i);
}
}
// main356 package cn.itcast.demo;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Demo2 {
public static void main(String[] args) {
Integer i=1;//装箱
int j=i;//拆箱
//典型应用
List list = new ArrayList();
list.add(1);
int k = (Integer)list.get(0);
Iterator it=list.iterator();
while(it.hasNext())
{
int m=(Integer)it.next();//拆箱
}
}
}
5 06-增强for循环
5.1 增强for循环
引入增强for循环原因:在JDK5以前的本中,遍历数组或集合中的元素,需先获得数组的长度或集合的迭代器,比较麻烦!
因此JDK5中定义了一种新的语法——增强for循环,以简化此类操作。增强for循环只能用在数组、或实现Iterator接口的集合类上
语法格式:
for(变量类型变量 :需迭代的数组或集合){
}
Map map=new HashMap();
//Map map2=new LinkedHashMap
map.put("1", "aaa");
map.put("2", "bbb");
map.put("3", "ccc");
//传统方式1
Set set=map.keySet();
Iterator it=set.iterator();
while(it.hasNext()){
String key=(String)it.next();
String value=(String) map.get(key); System.out.println("key="+key+",value="+value);
} //增强for循环的1种方式
for(Object obj:map.keySet()){
String key2=(String)obj;
String value2=(String)map.get(key2); System.out.println("key2="+key2+",value2="+value2);
}
//传统方式2
Set set2=map.entrySet();
Iterator it2=set2.iterator();
while(it2.hasNext()){
Map.Entry entry=(Entry)it2.next(); System.out.println("key="+entry.getKey()+",value="+entry.getValue());
} //增强for循环的2种方式
for(Object obj:map.entrySet()){
Map.Entry entry3=(Entry) obj;
String key3=(String) entry3.getKey();
String value3=(String) entry3.getValue();
System.out.println("key3="+key3+",value3="+value3);
}
//增强for循环需要注意的问题:只适合取数据
int arr[]={1,2,3};
for(int i: arr){
i=10;
}
System.out.println(arr[0]); // 1
List li=new ArrayList();
li.add("1");
for(Object obj : li){
obj="888";
}
System.out.println(li.get(0));// 1
6 可变参数
测试JDK中具有可变参数的类Arrays.asList()方法。分别传多个参、传数组,传数组又传参的情况。
注意:传入基本数据类型数组的问题。
从JDK 5开始, Java 允许为方法定义长度可变的参数。语法:
public void foo(int … args){
}
注意事项:
调用可变参数的方法时, 编译器将自动创建一个数组保存传递给方法的可变参数,因此,程序员可以在方法体中以数组的形式访问可变参数
可变参数只能处于参数列表的最后, 所以一个方法最多只能有一个长度可变的参数
public void testSum(){
sum(1,2,3,4);
int arr[]={5,6,7};
sum(arr);
}
public void sum(int ...nums){
//可变参数当成数组
int sum=0;
for(int i:nums){
sum+=i;
}
System.out.println(sum);
} public void bb(){
//public static
List list=Arrays.asList("1","2","3");
System.out.println(list);//[1, 2, 3]
String arr[]={"1","2","3","4"};
list=Arrays.asList(arr);
System.out.println(list);//[1, 2, 3, 4]
int nums[]={1,2,3,4,5};
list=Arrays.asList(nums);
System.out.println(list);//[[I@120d62b]
Integer nums2[]={1,2,3,4,5};
list=Arrays.asList(nums2);
System.out.println(list);//[1, 2, 3, 4, 5]
}
//可变参数注意的问题
//public void aa(int ...nums,int s){}//不可以
//public void bb(int s ,int ...nums)//可以
7 枚举类
为什么需要枚举?
一些方法在运行时,它需要的数据不能是任意的,而必须是一定范围内的值,此类问题在JDK5以前采用自定义带有枚举功能的类解决,Java5以后可以直接使用枚举予以解决。
JDK 5新增的 enum 关键字用于定义一个枚举类。
7.1 枚举类
枚举类具有如下特性:
枚举类也是一种特殊形式的Java类。
枚举类中声明的每一个枚举值代表枚举类的一个实例对象。
与java中的普通类一样,在声明枚举类时,也可以声明属性、方法和构造函数,但枚举类的构造函数必须为私有的(这点不难理解)。
枚举类也可以实现接口、或继承抽象类。
JDK5中扩展了swith语句,它除了可以接收int, byte, char, short外,还可以接收一个枚举类型。
若枚举类只有一个枚举值,则可以当作单态设计模式使用。
练习:请编写一个关于星期几的枚举WeekDay,要求:
枚举值:Mon、Tue 、Wed 、Thu 、Fri 、Sat 、Sun
该枚举要有一个方法,调用该方法返回中文格式的星期。
Java中声明的枚举类,均是java.lang.Enum类的孩子,它继承了Enum类的所有方法。常用方法:
name()
ordinal()//返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。
valueof(Class enumClass, String name) //返回带指定名称的指定枚举类型的枚举常量。
//String str=”B”;Grade g=Grade.valueOf(Grade.class,str);
values() 此方法虽然在JDK文档中查找不到,但每个枚举类都具有该方法,它遍历枚举类的所有枚举值非常方便。
package cn.itcast.enumeration;
import org.junit.Test;
public class Demo1 {
@Test
public void test() {
print(Grade.B);
}
public void print(Grade g) // A B C D E
{
String value=g.getValue();
System.out.println(value);
}
}
/*
* class Grade{ private Grade(){ }
* public static final Grade A=new Grade();
* public static final Grade B=new Grade();
* public static final Grade C=new Grade();
* public static final Grade D=new Grade();
* public static final Grade E=new Grade();
* }
*/
//如何定义枚举的构造函数、方法、字段
enum Grade {// class A 100-90 B 89-80 C 79-70 D 69-60 E 59-0
A("100-90"), B("89-80"), C("79-70"), D("69-60"), E("59-0");// object
private String value;
private Grade(String value){
this.value=value;
}
public String getValue(){
return this.value;
}
} package cn.itcast.enumeration2;
import org.junit.Test;
public class Demo1 {
@Test
public void test() {
print(Grade.B); //89-80,良
}
public void print(Grade g) // A B C D E
{
String value=g.getValue();
String value2=g.localeValue();
System.out.println(value+","+value2);
}
}
//带抽象方法的枚举
enum Grade {// class A 100-90优 B 89-80良 C 79-70 一般D 69-60差 E 59-0不及格
A("100-90"){
public String localeValue(){
return "优";
}
},
B("89-80"){
public String localeValue(){
return "良";
}
},
C("79-70"){
public String localeValue(){
return "一般";
}
},
D("69-60"){
public String localeValue(){
return "差";
}
},
E("59-0"){
public String localeValue(){
return "不及格";
}
};// object
private String value;
private Grade(String value){
this.value=value;
}
public String getValue(){
return this.value;
}
public abstract String localeValue();
}
7.2 反射什么—Class类
反射就是把Java类中的各种成分映射成一个个的java对象。例如,一个类有:成员变量,方法,构造方法,包等等信息,利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个对象。
Class类用于表示.class文件,画图演示一个对象的创建过程。
如何得到某个class文件对应的class对象。
类名.class, 对象.getClass() Class.forName(“类名”)
以上三种方式,JVM都会把相应class文件装载到一个class对象中(只装载一次)
创建类的实例:Class.newInstance方法
数组类型的Class实例对象
Class.isArray()
总之,只要是在源程序中出现的类型,都有各自的Class实例对象,例如,int,void…
反射就是把Java类中的各种成分映射成一个个的java对象。例如,一个类有:成员变量,方法,构造方法,包等等信息,利用反射技术可以对一个类进行解剖,把各个组成部分映射成一个个对象。
掌握反射技术的要点在于:如何从一个class中反射出各个组成部分。反射出来的对象怎么用。
7.3 Constructor类
Constructor类代表某个类中的一个构造方法
得到某个类所有的构造方法:
例子:Constructor [] constructors= Class.forName("java.lang.String").getConstructors();
得到某一个构造方法:
例子: //获得方法时要用到类型
Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);
创建实例对象:
通常方式:String str = new String(new StringBuffer("abc"));
反射方式: String str = (String)constructor.newInstance(new StringBuffer("abc"));
Class.newInstance()方法:例子:String obj = (String)Class.forName("java.lang.String").newInstance();
该方法内部先得到默认的构造方法,然后用该构造方法创建实例对象。
7.4 Field类
Field类代表某个类中的一个成员变量
问题:得到的Field对象是对应到类上面的成员变量,还是对应到对象上的成员变量?类只有一个,而该类的实例对象有多个,如果是与对象关联,哪关联的是哪个对象呢?所以字段fieldX 代表的是x的定义,而不是具体的x变量。(注意访问权限的问题)
示例代码:
ReflectPoint point = new ReflectPoint(1,7);
Field y = Class.forName("cn.itcast.corejava.ReflectPoint").getField("y");
System.out.println(y.get(point));
//Field x = Class.forName("cn.itcast.corejava.ReflectPoint").getField("x");
Field x = Class.forName("cn.itcast.corejava.ReflectPoint").getDeclaredField("x");
x.setAccessible(true);
System.out.println(x.get(point));
7.5 Method类
Method类代表某个类中的一个成员方法
得到类中的某一个方法:
例子: Method charAt = Class.forName("java.lang.String").getMethod("charAt", int.class);
调用方法:
通常方式:System.out.println(str.charAt(1));
反射方式:System.out.println(charAt.invoke(str, 1));
如果传递给Method对象的invoke()方法的第一个参数为null,这有着什么样的意义呢?说明该Method对象对应的是一个静态方法!
jdk1.4和jdk1.5的invoke方法的区别:
Jdk1.5:public Object invoke(Object obj,Object... args)
Jdk1.4:public Object invoke(Object obj,Object[] args),即按jdk1.4的语法,需要将一个数组作为参数传递给invoke方法时,数组中的每个元素分别对应被调用方法中的一个参数,所以,调用charAt方法的代码也可以用Jdk1.4改写为 charAt.invoke(“str”, new Object[]{1})形式。
7.6 用反射方式执行某个类中的main方法
目标:写一个程序,这个程序能够根据用户提供的类名,去执行该类中的main方法。用普通方式调完后,大家要明白为什么要用反射方式去调啊?
问题:
启动Java程序的main方法的参数是一个字符串数组,即public static void main(String[] args),通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?按jdk1.5的语法,整个数组是一个参数,而按jdk1.4的语法,数组中的每个元素对应一个参数,当把一个字符串数组作为参数传递给invoke方法时,javac会到底按照哪种语法进行处理呢?jdk1.5肯定要兼容jdk1.4的语法,会按jdk1.4的语法进行处理,即把数组打散成为若干个单独的参数。所以,在给main方法传递参数时,不能使用代码mainMethod.invoke(null,new String[]{“xxx”}),javac只把它当作jdk1.4的语法进行理解,而不把它当作jdk1.5的语法解释,因此会出现参数类型不对的问题。
解决办法:
mainMethod.invoke(null,new Object[]{new String[]{"xxx"}});
mainMethod.invoke(null,(Object)new String[]{"xxx"}); ,编译器会作特殊处理,编译时不把参数当作数组看待,也就不会数组打散成若干个参数了
package cn.itcast.reflect;
import java.io.InputStream;
import java.util.List;
public class Person {
public String name="aaaa";
private int password;
private static int age=23;
public Person(){
System.out.println("person");
}
public Person(String name){
this.name=name;
System.out.println("person name");
}
public Person(String name,int password){
this.name=name;
System.out.println("person name password");
}
private Person(List list){
System.out.println("list");
}
public void aa1(){
System.out.println("aa1");
}
public void aa1(String name,int password){
System.out.println("name= "+name+" password="+password);
}
public Class[] aa1(String name,int[] password){
return new Class[]{String.class};
}
private void aa1(InputStream in){
System.out.println(in);
}
public static void aa1(int num){
System.out.println(num);
}
public static void main(String []args){
System.out.println("main");
}
} package cn.itcast.reflect;
import java.lang.reflect.Field;
import org.junit.Test;
//反射类的字段
public class Demo4 {
//public String name="aaaa";
@Test
public void test1() throws Exception{
Class clazz=Class.forName("cn.itcast.reflect.Person");
Field f=clazz.getField("name");
Person p=new Person();
Object value= f.get(p);//获取字段值
Class type=f.getType();//字段类型
System.out.println(type);//class java.lang.String
if(type.equals(String.class)){
String S_value=(String)value;
System.out.println(S_value);//aaaa
}
//设置值
f.set(p, "ppppp");
System.out.println(f.get(p));//ppppp
System.out.println(String.class);//class java.lang.String
}
//private int password;
@Test
public void test2() throws Exception{
Class clazz=Class.forName("cn.itcast.reflect.Person");
Field f=clazz.getDeclaredField("password");
f.setAccessible(true);
Person p=new Person();
f.set(p, 123);
System.out.println(f.get(p));//123
}
//private static int age=23;
@Test
public void test3() throws Exception{
Class clazz=Class.forName("cn.itcast.reflect.Person");
Field f=clazz.getDeclaredField("age");
f.setAccessible(true);
System.out.println(f.get(null));//23
}
}
package cn.itcast.reflect;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
//反射类的构造函数,创建类的对象
public class Demo2 {
//public Person()
@Test
public void test1() throws Exception{
Class clazz=Class.forName("cn.itcast.reflect.Person");
Constructor c=clazz.getConstructor(null);
Person p=(Person) c.newInstance(null);//person
System.out.println(p.name);//aaaa
}
//public Person(String name)
@Test
public void test2() throws Exception{
Class clazz=Class.forName("cn.itcast.reflect.Person");
Constructor c=clazz.getConstructor(String.class);
Person p=(Person) c.newInstance("abc");//person name
System.out.println(p.name);//abc
}
//public Person(String name,int password)
@Test
public void test3() throws Exception{
Class clazz=Class.forName("cn.itcast.reflect.Person");
Constructor c=clazz.getConstructor(String.class,int.class);
Person p=(Person) c.newInstance("abc",999);//person name password
System.out.println(p.name);//abc
}
//private Person(List list)
@Test
public void test4() throws Exception{
Class clazz=Class.forName("cn.itcast.reflect.Person");
Constructor c=clazz.getDeclaredConstructor(List.class);
c.setAccessible(true);//暴力反射,统统打开访问权限
Person p=(Person) c.newInstance(new ArrayList());//list
System.out.println(p.name);//aaaa
}
//创建对象的另外一种途径,无参构造方法,等效test1
public void test5() throws Exception{
Class clazz=Class.forName("cn.itcast.reflect.Person");
Person p=(Person) clazz.newInstance();
System.out.println(p.name);//aaaa
}
} package cn.itcast.reflect;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import org.junit.Test;
//反射方法
public class Demo3 {
// public void aa1()
@Test
public void test1() throws Exception{
Class clazz=Class.forName("cn.itcast.reflect.Person");
Method method=clazz.getMethod("aa1", null);
Person p=new Person();//person
method.invoke(p, null);//aa1
}
//public void aa1(String name,int password)
@Test
public void test2() throws Exception{
Class clazz=Class.forName("cn.itcast.reflect.Person");
Method method=clazz.getMethod("aa1", String.class,int.class);
Person p=new Person();//person
method.invoke(p, "xxxx",99);//name= xxxx password=99
}
//public Class[] aa1(String name,int[] password)
@Test
public void test3() throws Exception{
Class clazz=Class.forName("cn.itcast.reflect.Person");
Method method=clazz.getMethod("aa1", String.class,int[].class);
Person p=new Person();//person
Class cs[]=(Class[]) method.invoke(p, "xxxx",new int[]{1,2,3});//name= xxxx password=99
System.out.println(cs[0]);//class java.lang.String
}
//private void aa1(InputStream in)
public void test4() throws Exception{
Class clazz=Class.forName("cn.itcast.reflect.Person");
Method method=clazz.getDeclaredMethod("aa1",InputStream.class);
method.setAccessible(true);
Person p=new Person();//person
method.invoke(p,new FileInputStream("C:\\1.txt"));//
}
//public static void aa1(int num)
public void test5() throws Exception{
Class clazz=Class.forName("cn.itcast.reflect.Person");
Method method=clazz.getMethod("aa1",int.class);
method.invoke(null,777);//777 静态方法调用不需要对象,给对象也行
}
// public static void main(String []args){
public void test6() throws Exception{
Class clazz=Class.forName("cn.itcast.reflect.Person");
Method method=clazz.getMethod("main",String [].class);
//method.invoke(null,new String[]{"a","c"});//Wrong
//method.invoke(null,"a","c");//Wrong
String []str={"x","y","z"};
method.invoke(null, (Object)str);
method.invoke(null, new Object[]{new String[]{"a","c"} });
method.invoke(null, (Object)new String[]{"a","c"});
}
}
7.7 用反射技术实现一个简单的web服务器
内省(Introspector) — JavaBean
Introspector 类为通过工具学习有关受目标 Java Bean 支持的属性、事件和方法的知识提供了一个标准方法。
什么是JavaBean和属性的读写方法?
有get或set方法就是一个属性,另外所有类继承了Object类的getClass()方法,所以还有一个属性class。
访问JavaBean属性的两种方式:
直接调用bean的setXXX或getXXX方法。
通过内省技术访问(java.beans包提供了内省的API),内省技术访问也提供了两种方式。
通过PropertyDescriptor类操作Bean的属性
通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法。
什么情况下用内省?
package cn.itcast.introspector;
//该类共有5个属性
public class Person {
private String name;
private String password;
private int age;
public void setAb(int a){
}
public String getName() {
return name;
}
public String getPassword() {
return password;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setPassword(String password) {
this.password = password;
}
public void setAge(int age) {
this.age = age;
}
} package cn.itcast.introspector;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.junit.Test;
public class Demo1 {
//得到bean所有属性
public void test1() throws IntrospectionException{
BeanInfo info=Introspector.getBeanInfo(Person.class);
//去掉Object里的属性
BeanInfo info2=Introspector.getBeanInfo(Person.class,Object.class);
PropertyDescriptor[] pds=info.getPropertyDescriptors();
for(PropertyDescriptor pd:pds){
System.out.println(pd.getName());
//ab age class name password
}
}
//操纵bean的指定属性:age
@Test
public void test2() throws Exception{
Person p=new Person();
PropertyDescriptor pd=new PropertyDescriptor("age", Person.class);
//得到属性的写方法,为属性赋值
Method method=pd.getWriteMethod();
method.invoke(p, 45);
System.out.println(p.getAge());//45
//获取属性的值
method=pd.getReadMethod();
System.out.println(method.invoke(p, null));//45
}
//高级内容,获取当前操作的属性的类型
@Test
public void test3() throws Exception{
Person p=new Person();
PropertyDescriptor pd=new PropertyDescriptor("age", Person.class);
//得到属性的写方法,为属性赋值
Method method=pd.getWriteMethod();
System.out.println(pd.getPropertyType());//int
method.invoke(p, 45);
System.out.println(p.getAge());//45
//获取属性的值
method=pd.getReadMethod();
System.out.println(method.invoke(p, null));//45
}
}
7.8 内省—beanutils工具包
Apache组织开发了一套用于操作JavaBean的API,这套API考虑到了很多实际开发中的应用场景,因此在实际开发中很多程序员使用这套API操作JavaBean,以简化程序代码的编写。
在工程下新建lib目录,导入commons-beanutils-1.8.3.jar 和支持包commons-logging-1.1.1.jar
选中两个包,右键build path/add to build path
Beanutils工具包的常用类:
BeanUtils
PropertyUtils
ConvertUtils.regsiter(Converter convert, Class clazz)
自定义转换器
package cn.itcast.beanutils;
import java.util.Date;
public class Person {
private String name;
private String password;
private int age;
private Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getName() {
return name;
}
public String getPassword() {
return password;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setPassword(String password) {
this.password = password;
}
public void setAge(int age) {
this.age = age;
}
} package cn.itcast.beanutils;
import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConversionException;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
import org.junit.Test;
//使用beanUtils操纵bean的属性 ( 第三方)
public class Demo1 {
@Test
public void test1() throws Exception{
Person p=new Person();
BeanUtils.setProperty(p, "age", 456);
System.out.println(p.getAge());//456
}
@Test
public void test2() throws Exception{
String name="aaaa";
String age="123";
String password="pw";
Person p=new Person();
//支持8种基本类型自动转换
BeanUtils.setProperty(p, "name", name);
BeanUtils.setProperty(p, "age", age);
BeanUtils.setProperty(p, "password", password);
System.out.println(p.getName());//aaaa
System.out.println(p.getAge());//123
System.out.println(p.getPassword());//pw
}
@Test
public void test3() throws Exception{
String birthday="1983-12-1";
//为了让日期赋值到bean的birthday属性上,给beanUtils注册一个日期转换器
//ConvertUtils.register(converter, clazz);
ConvertUtils.register(new Converter(){
public Object convert(Class type, Object value) {
if(value==null) return null;
if(!(value instanceof String)){
throw new ConversionException("只支持String类型的转换");
}
String str=(String)value;
if(str.trim().equals("")) return null;
SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd",Locale.US);
try {
return df.parse(str);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}, Date.class);
Person p=new Person();
BeanUtils.setProperty(p, "birthday", birthday);
System.out.println(p.getBirthday());//pw
System.out.println("___"+BeanUtils.getProperty(p, "birthday"));
}
public void test5() throws Exception {
Map map=new HashMap();
map.put("name", "aaa");
map.put("password", "123");
map.put("brithday", "1980-09-09");
ConvertUtils.register(new DateLocaleConverter(), Date.class);
Person p=new Person();
//用map集合填充bean属性,map关键字和bean属性要一致
BeanUtils.populate(p, map);
}
}
7.9 泛型(Generic)—泛形的作用
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
ArrayList
ArrayList
整个称为ArrayList
整个ArrayList
7.10 泛型典型应用
使用迭代器迭代泛形集合中的元素。
使用增强for循环迭代泛形集合中的元素。
存取HashMap中的元素。
使用泛形时的几个常见问题:
使用泛形时,泛形类型须为引用类型,不能是基本数据类型
//使用泛型时,如果两边都使用到泛型,两边必须一样
ArrayList