【javaweb就业班】day02资料 内省和BeanUtils框架,XML入门

cn.itcast.java.introspector.Demo1:用SUN提供内省API,操作JavaBean属性

package cn.itcast.java.introspector;

//狭义的JavaBean
public class Student {
	public String getName() {
		return "jack";
	}
	public int getAge() {
		return 31;
	}
	public String getWC(){
		return "WC";
	}
}
package cn.itcast.java.introspector;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import org.junit.Test;

public class Demo1 extends Object{ // 因为Object类中有名为“class”的属性
	@Test
	public void test1() throws Exception{
		
		Student s = new Student(); // 也可以使用反射的方法获得Student对象;
		
		//pd引用Student的name属性
		PropertyDescriptor pd = new PropertyDescriptor("name",Student.class); // 参数一:属性名, 参数二:属性所属的类
		
		//m = setName()
		Method m = pd.getWriteMethod();   // 内省一定是站在反射的高度上看问题;
		
		//s.setName("berry")
		m.invoke(s,"berry");
		
		//s.getName()
		m = pd.getReadMethod();
		String returnValue = (String) m.invoke(s,null); // invoke()默认返回Object对象
		
		System.out.println("returnValue="+returnValue);
		
			//   --------  这就是内省API操作javaBean;(站在反射的角度)
	}
	
	
	 // 解决一个类有有哪些属性, 个数
	@Test 
	public void test2() throws Exception{
		//BeanInfo表示该Student对象所有的属性情况(所有的属性集合)
		BeanInfo bi = Introspector.getBeanInfo(Student.class);
		
		//取得Student对象所有属性集合
		PropertyDescriptor[] pds = bi.getPropertyDescriptors();  // 单个属性getPropertyDescriptor()
		
		for(PropertyDescriptor pd : pds){
			System.out.println(pd.getName());	
		}
	}
}

             1) 内省,一定是站在“反射”的高度,  

             2)PropertyDescriptor就代表了某个属性,比如name属性,和它的setter和getter方法

                   PropertyDescriptor[] pds = bi.getPropertyDescriptors();  就代表bi这个javabean的所有属性及属性对应的setter和getter方法

             3) 内省API(SUN公司开发)站在反射角度

   1)  在操作JavaBean时,即对JavaBean进入setter和getter操作时
   2)属性和getXxxxx()有关,同时getXxxxx()必须有返回值
         没有对应的 getXxxxx()的只能叫做字段,不能成为属性,
   3)任何一个JavaBean都有一个class属性,来自于Object类。 
  

总结:

sun公司的内省的作用:操作javabean的存取方法; 取得某个javabean的属性的名字,和属性的个数


*3 BeanUtils框架/工具(APACHE开源组织开发)
    因为sun公司的内省API操作javabean的属性不太方便,所以这里有了“BeanUtils框架”新的替代它;
    需要自己下载commons-beanutils-1.8.0-sources包
    在day02目录下 -- 建立lib文件夹 -- 拷贝commons-beanutils-1.8.0.jar
    选中lib中的commons-beanutils-1.8.0.jar -- 右键 -- add to build path
    
    commons-beanutils-1.8.0.jar包依赖于commons-logging.jar这个日志包
    选中lib中的commons-logging.jar -- 右键 -- add to build path

       1)BeanUtils框架能够完成内省API的一切功能,而且优化
       2)BeanUtils框架能够对String<->8种基本类型自动转化
       3)BeanUtils框架自定义转换器:
        ConvertUtils.register( 转换规则 ,目标对象的Class)
        
        Student s = new Student();
        BeanUtils bu = new BeanUtils();
        /*
        //向BeanUtils框架注册自定义的转换器(String -> java.util.Date) ,     项目中可能会有各种各样的类型转换,就可以使用这个模式;
        //因为BeanUtils默认是不可以将String类型转成Date类型; BeanUtils只能完成String和基本类型的转换;
        ConvertUtils.register(new Converter(){
            public Object convert(Class clazz, Object type) {
                //参数一:java.util.Date.class(目标类型)
                //参数二:是传入的参数类型,即java.lang.String
                String strBirthday = (String) type; // Object强转为String;
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// SimpleDateFormat就具有Date和String相互转换的功能
                try {
                    return sdf.parse(strBirthday);
                } catch (ParseException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        },java.util.Date.class);
        
        bu.setProperty(s,"birthday","2011-10-09");  // 自定义转换器要在此句话之前;
        String birthday = bu.getProperty(s,"birthday");
        System.out.println("birthday="+new Date(birthday).toLocaleString());
        
       4) 向BeanUtils框架注册自定义转换器必须放在bu.setProperty()代码之前    
       5) 使用BeanUtils内置String->Date的转换器:
        ConvertUtils.register(new DateLocaleConverter(),java.util.Date.class);
       6) 绑定源码,--- 按住Ctrl,并点击 Collections -- attache -- External folder -- C盘下的jdk目录 -- 选中src.zip -- 确定
       7) 查看源码时,如何想看某个类都有哪些方法 -- IDE -- Window -- show view -- outline -

cn.itcast.java.beanutils.Demo1:用APACHE提供Bean工具API操作JavaBean类属性

package cn.itcast.java.beanutils;

import java.util.Date;  // 注意一遇见Date,就导入这个包;

//狭义JavaBean
public class Student {
	private String name;
	private int age;
	private Date birthday;
	public Student(){}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
}
package cn.itcast.java.beanutils;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
import org.junit.Test;

public class Demo1 {
	@Test
	public void test1() throws Exception{
		Student s = new Student();
		BeanUtils bu = new BeanUtils();
		
/*		
		//向BeanUtils框架注册我们自定义的转换器(String -> java.util.Date) ,     项目中可能会有各种各样的类型转换,就可以使用这个模式;
		//因为BeanUtils默认是不可以将String类型转成Date类型; BeanUtils只能完成String和基本类型的转换;
		ConvertUtils.register(new Converter(){
			public Object convert(Class clazz, Object type) {
				//参数一:java.util.Date.class(目标类型)
				//参数二:是传入的参数类型,即java.lang.String
				String strBirthday = (String) type; // Object强转为String;
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// SimpleDateFormat就具有java.util.Date和String相互转换的功能
				try {
					return sdf.parse(strBirthday);
				} catch (Exception e) {
					e.printStackTrace();
					return null;
				}
                //  注意这里是不能抛的,只能catch;  自己体会原因
			}
		},java.util.Date.class);
		
        
        // 这里Converter是一个接口,在基础班中讲过的,当某个接口中只有一个或者两个为实现的方法时;我们可以使用匿名内部类的方式实现类

		bu.setProperty(s,"birthday","2011-10-09");  // 自定义转换器要在此句话之前;
		String birthday = bu.getProperty(s,"birthday");
		System.out.println("birthday="+new Date(birthday).toLocaleString());
		*/
		
		ConvertUtils.register(new DateLocaleConverter(),java.util.Date.class);  // 使用BeanUtils框架自带的String -> java.util.Date转换器DateLocaleConverter;
		
		bu.setProperty(s,"name","张三");
		bu.setProperty(s,"age","31"); // 本来age是int型的, 这里传入的是String类型; --- BeanUtils框架能够对String<->基本类型自动转化
		bu.setProperty(s,"birthday","2011-10-09"); // BeanUtils默认不能将String类型转成Date类型; Date不是基本类型;
		
		
		String name = bu.getProperty(s,"name");
		String age = bu.getProperty(s,"age");
		String birthday = bu.getProperty(s,"birthday");
		
		
		
		System.out.println("name="+name); 
		System.out.println("age="+age);
//		System.out.println("birthday="+new Date(birthday).toLocaleString());  //这句运行会报错
		System.out.println("birthday="+birthday);
//		System.out.println("birthday=" + birthday);  默认等价于 System.out.println("birthday=" + birthday.toString() )
	}
}

*4 泛型
   1) 在编译时,由编译器约束放入集合中的类型
   2)在运行时,编译器会擦除原泛型类型
   3)泛型两边要么都不使用约束,要么二边约束一致类型,同时二边必须使用引用类型
   4)为了与JDK1.4兼容,泛型可以一边有约束,一边无约束
   思考:不利用中间变量,将二个数交互
   5)当一个类中出大量的泛型方法或属性/字段,此时可以将该类作成泛型类
   6)如果使用泛型通配符,只能获取与泛型具体类型无关的信息,例如:长度。
   7)有两个类,初学者一定要注意:Collections和Arrays,  重点掌握
      Collections.reverse(stringList); // 现成的reverse方法;  还有sort方法,swap,
                                       // 有二个类,初学者一定要注意:Collections和Arrays,  提供了很多已有的工具

cn.itcast.java.generic.Demo1:传统方式下运行时对集合内容安全检查,统计各类型变量的数量

package cn.itcast.java.generic;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

//传统方式下,对集合判断
public class Demo1 {
	public static void main(String[] args) {
		
		List<Boolean> list = new ArrayList<Boolean>();
		list.add(true);
		list.add(false);
		for(Boolean b : list){
			System.out.println(b);
//			System.out.println(b.toString()); 和上面等价;
		}
		
		/*
		int stringNum = 0,integerNum=0,booleanNum = 0;
		List list = new ArrayList();
		list.add("jack");
		list.add("marry");
		list.add("sisi");
		list.add(100);
		list.add(200);
		list.add(true);
		Iterator it = list.iterator();
		while(it.hasNext()){
			Object obj = it.next();
			if(obj instanceof String){
				stringNum++;
			}else if(obj instanceof Integer){      //  判断obj引用是是否为Integer类型;
				integerNum++;
			}else if(obj instanceof Boolean){
				booleanNum++;
			}
		}
		System.out.println("stringNum="+stringNum);
		System.out.println("integerNum="+integerNum);
		System.out.println("booleanNum="+booleanNum);
		*/
	}
}

cn.itcast.java.generic.Demo3:使用泛型方法交换二元素

package cn.itcast.java.generic;

public class Demo3 {
	public static void main(String[] args) {
		Boolean numA = false;
		Boolean numB = true;
		System.out.println("numA" + numA);
		System.out.println("numB" + numB);
		swap(numA,numB);   // 这里都是把numA和numB的副本传递了过去;
	}
	
	//泛型方法(通用方法)
	public static <T> void swap(T numA,T numB) {   // <T>表示声明T是一种类型;
		T temp = numA;
		numA = numB;
		numB = temp;
		System.out.println("numA" + numA);
		System.out.println("numB" + numB);
	}
	
	/*public static <T,V> V getValue(K key){
	 	return map.get(key);
	 }
	 */
}

 

cn.itcast.java.generic.Demo4:泛型通配符

package cn.itcast.java.generic;


// 泛型类   -- 当一个类中有大量的泛型方法,或者泛型属性
public class Apple<T> {
	/*
	public void buy(Integer num){
		System.out.println("苹果:" + num  + "个");
	}
	public void buy(Double price){
		System.out.println("苹果:" + price  + "元");
	}
	*/
	
	//泛型方式
	public void buy(T t){
		System.out.println("苹果:" + t  + "信息");
	}
}
package cn.itcast.java.generic;

public class Demo4 {
	public static void main(String[] args) {
		/*
		Apple a1 = new Apple();
		a1.buy(10);
		a1.buy(5.5);
		*/
		Apple<Integer> a1 = new Apple<Integer>();
		a1.buy(10);
		Apple<Double> a2 = new Apple<Double>();
		a2.buy(5.5);
		
	}
}

cn.itcast.java.generic.Demo5:有限制的通配符

package cn.itcast.java.generic;

import java.util.ArrayList;
import java.util.List;

//泛型通配符?号的使用
public class Demo5 {
	public static void main(String[] args) {
		List<Boolean> booleanList = new ArrayList<Boolean>();
		booleanList.add(true);
		booleanList.add(false);
		show(booleanList);
		
		
		/*Vector<? extends Number>  x = new Vector<Integer>();  // 限定通配符的上界 ,  因为Number是Integer的父类
		Vector<? super Integer>  x = new Vector<Number>();  // 限定通配符的下界
*/		
		// String在API文档中定义的是final, 也就是String类任何人都无法继承它;
		
		
	}
	public static void show(List<?> list) {  // List<?> list
		System.out.println("集合长度为:" + list.size());
		for(Object o : list){ // 这里一定要写Object o,不能写具体类型;
			System.out.println(o);
		}
	}
}

              1) 我自己写了一个show()方法,但是我们不知道别的人穿过来的list中放的数据的具体类型

                     就可以使用:List<?> list,来接收参数

              2) 遍历这个List<?> list时,就只能用Object来保存临时元素

猜你喜欢

转载自blog.csdn.net/iNiBuBian/article/details/88136583