码迷,mamicode.com
首页 > 编程语言 > 详细

java新特性下

时间:2015-01-16 19:13:29      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:java   泛型   框架   

  • 泛型
为什么需要泛型,什么是泛型?
对象类型数据保存到集合中时,会丢失其类型,取出时变成Object类型,Object类型需要强转回丢失的数据类型,这容易导致程序员的误操作问题,带来安全性!泛型就是给集合强制其只能保存一种数据类型,从而不会出现元素数据类型丢失问题!!
package 泛型;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.junit.Test;

public class Generic泛型出现原因 {
	
	@Test
	public void test() {
		// 程序员编写代码,忘记所转换的类型,但项目编码时并不报错
		/*ArrayList al = new ArrayList();
		al.add("123");
		Integer num = (Integer)al.get(0);	//编码时不出错
		System.out.println(num);*/
		
		List<String> list1 = new ArrayList<String>();//声明该集合只能处理String类数据
		list1.add("1");
		list1.add("2");
		list1.add("3");
		
		Iterator<String> it = list1.iterator();
		while(it.hasNext()){
			String value = it.next();
			System.out.println(value);
		}
		
		for(String num : list1){
			System.out.println(num);
		}
	}
	
	@Test
	public void test2(){
		//HashMap可能会导致取的顺序和存入时的顺序不一致,我们可以选择采用LinkedHashMap
		//购物车用到
	//	Map<Integer , String> map = new LinkedHashMap<Integer, String>();
		Map<Integer , String> map = new HashMap<Integer, String>();
		map.put(1, "aa");
		map.put(2, "bb");
		map.put(3, "cc");
		map.put(4, "dd");
		map.put(5, "ee");
		map.put(6, "ff");
		
		//set具体取出步奏
		Set<Entry<Integer, String>> set = map.entrySet();
		Iterator<Entry<Integer, String>> it = set.iterator();
		while(it.hasNext()){	
			Entry<Integer,String> e = it.next();
			Integer key = e.getKey();
			String value = e.getValue();
			System.out.println("key:"+key+" value:"+ value);
		}
		
		//增强for循环取出元素
		for(Entry<Integer,String> e : map.entrySet()){
			Integer key = e.getKey();
			String value = e.getValue();
			System.out.println("key:"+key+" value:"+ value);
		}
		
	}
}
package 泛型;

import org.junit.Test;
//自定义泛型方法(自定义泛型类支持单元测试)
public class 自定义泛型<T> {//类上面声明的泛型作用在整个类上,但是不作用在STATIC方法上

		@Test
		public void testa(){
			//String b = a("aaa");
			//System.out.println(b);
		}
		//先声明,再使用
		public <E,K>  T a(T t, E e,K k){	//泛型的本质就是将数据类型也参数化
			System.out.println(t);
			return t;
		}
		
		//先声明,再使用
		public T a(T t){	//泛型的本质就是将数据类型也参数化
			System.out.println(t);
			return t;
		}
		//编写一个泛型方法实现指定数组元素的交换
		public static <T> void change(T[] arr1 ,int m , int n ){
			T temp = arr1[m];
			arr1[m] = arr1[n];
			arr1[n] = temp;
		}	
		
		//编写一个泛型方法,颠倒数组元素
		public  void changAll(T[] arr){
			int start = 0;
			int end = arr.length-1;
			for(int i=end , j = start ;i > j ; i--,j++  ){
				T temp = arr[i];
				arr[i] = arr[j];
				arr[j] = temp;
			}
		}
		
		@Test
		public void testChange(){
			自定义泛型<String> zdy = new 自定义泛型<String>();
			String[] arr  = {"1","2","3","4","5"};
			zdy.changAll(arr);
			for(String s : arr)
			System.out.println(s);
		}
}

package 泛型;

import org.junit.Test;

public class 泛型类  <T,E>{//自定义泛型类,参数在整个类内有效
	
		public T getT(T t){
			return t;
		}
		@Test
		public void test(){
		泛型类<String,Integer> fxl = new 泛型类<String, Integer>();
		System.out.println(fxl.getT("adasd"));
		}
	}

  • 反射
什么是反射,为什么需要反射?
反射是做java框架用的技术,它可以根据用户提供的类路径和名称,得到其属性,方法,和构造函数。从而可以通过反射操作类和类实例,调用某个方法,给某个属性赋值!!
package 反射reflect;

import java.io.InputStream;
import java.util.List;

public class Person {
	
	public String address;
	public static String Sdept;
	private int age;
	private String name;
	private List list;

	public Person() {
		System.out.println("Person无参构造函数被执行");
	}

	private Person(List list) {
		this.list = list;
		System.out.println("list私有构造函数");
	}

	public Person(int age, String name) {
		this.age = age;
		this.name = name;
		System.out.println("age:" + age + ",name:" + name);
	}

	// ---------------------------------------------
	public void eat() {
		System.out.println("eat");
	}

	public void run(String name) {
		System.out.println("name:" + name);
		System.out.println("run");
	}

	public Class[] execute(String name, List list) {
		System.out.println("执行了Excute方法");
		return new Class[]{String.class};
	}
	
	private void excute2(InputStream in){
		System.out.println("执行了Excute2方法");
		System.out.println(in);
		
	}
	
	public static void excute3(int num){
		System.out.println("执行了Excute3方法");
		System.out.println(num);
	}
	
	public static void main(String[] args){
		System.out.println("main");
	}
	
	public void intArr(int[] arr){
		for(int i : arr){
			System.out.print(i+" ");
		}
	}
	
	public void StringArr(String[] arr){
		for(String s : arr){
			System.out.print(s + " ");
		}
	}
}

package 反射reflect;

import org.junit.Test;

/*
 * 加载类
 * 反射:
 * 0.创建xml配置文件
 * 1.读取配置文件的配置信息(通常为XML)
 * 2.加载配置文件中类
 * 3.解剖出加载类的属性(封装数据),构造方法(创建对象),方法(执行某一功能)
 */
public class Demo {
	
		@Test
		public void test() throws ClassNotFoundException{
			//加载类
			//方法一:
			Class clazz = Class.forName("myday01.src.反射reflect.Person");
			//方法二
			Class clazz1 = new Person().getClass();
			//方法三
			Class clazz2 = Person.class;
		}
}

package 反射reflect;

import java.util.List;
import java.lang.reflect.Constructor;
import java.util.ArrayList;

import org.junit.Test;

/*
 * 反射类的构造函数,创建类的对象
 */
public class Demo2 {

	@Test
	public void test() throws Exception {
		// 反射无参构造函数,pulic Person(){}
		// 加载
		Class clazz = Class.forName("反射reflect.Person");
		// 得到构造函数
		Constructor c = clazz.getConstructor(null);// 指定的无参构造函数
		// 通过构造函数创建对象
		Person p = (Person) c.newInstance(null);
	}

	// 反射有参的构造函数
	@Test
	public void test1() throws Exception {
		Class clazz = Class.forName("反射reflect.Person");
		Constructor c = clazz.getConstructor(int.class, String.class);
		Person p = (Person) c.newInstance(20, "li");
	}

	// 反射私有的构造函数,反射能够做到外部访问私有的构造函数
	@Test
	public void test2() throws Exception {
		Class clazz = Class.forName("反射reflect.Person");
		// getConstructor只能得到public类型的构造方法Constructor c =
		// clazz.getConstructor(List.class);
		Constructor c = clazz.getDeclaredConstructor(List.class);
		c.setAccessible(true);//暴力反射 ,使私有的构造函数能够外部访问
		Person p = (Person) c.newInstance(new ArrayList());
	}
	
	//创建对象的最简单途径(和第一中方法是一样的,默认调用无参构造函数)
	@Test
	public void test3() throws Exception{
		Class clazz = Class.forName("反射reflect.Person");
		Person p = (Person) clazz.newInstance();
	}
}

package 反射reflect;

import java.util.List;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import java.util.ArrayList;
import org.junit.Test;

//反射类的方法
public class Demo5反射Method {

		@Test
		public void test() throws Exception{
			Person p = new Person();
			Class clazz  = Class.forName("反射reflect.Person");
			Method m = clazz.getMethod("eat",null);	//得到方法名称为eat的方法,指定其参数为null
			m.invoke(p, null);	//对象p的方法执行,参数为空
			
			//反射普通类型
			Method m2 = clazz.getMethod("run", String.class);//得到方法名称为run的方法,指定其参数类型为String类型
			m2.invoke(p, "lj");//p对象执行此方法,参数名称为"lj"
			
			//反射String和List类型
			Method m3 = clazz.getMethod("execute", String.class , List.class);
			m3.invoke(p, "lj",new ArrayList());
			
			//反射InputStream类型
			Method m4 = clazz.getDeclaredMethod("excute2", InputStream.class);
			m4.setAccessible(true);
			m4.invoke(p, new FileInputStream("d://a.txt"));
			
			//反射静态方法的类
			Method m5 = clazz.getMethod("excute3", int.class);
			m5.invoke(null, 10);//静态对象在调用时候不需要对象,其他参数和反射普通方法并没有啥区别
	
			//反射main方法
			Method mm = clazz.getMethod("main", String[].class);
			mm.invoke(null,(Object)new String[]{"123"});	
			//JDK1.4并不存在可变参数(传递多个参数都是采用数组的形式来实现),
			//JDK1.5为了兼容1.4版本,把数组类参数在反射时都会拆成数组元素个数的参数来传递,
			//反射数组类型数据时,都可以先强制转换为Object类型来做
			
			//反射整型数组
			Method marr = clazz.getMethod("intArr",int[].class);
			marr.invoke(p, (Object) new int[]{1,2,3,4,5});//int数组类型测试过,不强转也是可以的
			
			//反射字符数组
			Method intrr = clazz.getMethod("StringArr", String[].class);
			intrr.invoke(p, (Object)new String[]{"1","2"});//String数组类型必须强转
		}
		
		
}

package 反射reflect;

import java.util.List;
import java.lang.reflect.Field;
import java.util.ArrayList;

import org.junit.Test;

public class Demo6反射字段 {

		@Test
		public void test() throws Exception{
			Person p = new Person();
			Class clazz = Class.forName("反射reflect.Person");
			//反射普通字段
			Field f = clazz.getField("address");
			Object fv =  f.get(p);	//获取到p对象的address字段的值
			if(f.getType().equals(String.class)){
				f.set(p, "重庆");
				String address = (String) f.get(p);
				System.out.println(address);
			}
			//反射private字段
			Field ff = clazz.getDeclaredField("age");
			ff.setAccessible(true);
			if(ff.getType().equals(int.class)){
				ff.set(p, 20);
				int ffvalue  = (Integer) ff.get(p);
				System.out.println(ffvalue);
			}
			//反射List
			Field fl = clazz.getDeclaredField("list");
			fl.setAccessible(true);
			if(fl.getType().equals(List.class)){
				List alist = new ArrayList();
				alist.add(1);
				alist.add(2);
				alist.add(3);
				alist.add(4);
				fl.set(p, alist);
				List list = (List) fl.get(p);
				for(Object i:alist)
				System.out.print((Integer)i + " ");
			}
			//反射静态字段
			Field fs = clazz.getField("Sdept");
			if(fs.getType().equals(String.class)){
				fs.set(null, "\n计算机工程试验中心");
				String fsv = (String) fs.get(null);
				System.out.println(fsv);
			}
			
		}
}
  • 内省
什么是内省,内省有什么用?
内省也是做框架经常用到的一项技术。
个人理解:内省是对反射属性的技术补充,反射对属性操作过于麻烦,于是出现了内省

package 内省introspector;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;

import org.junit.Test;

//使用内省API操作Bean的属性
public class Demo {
		//获取bean内的所有属性
		@Test
		public void test1() throws Exception{
		///在 Java Bean 上进行内省,了解其所有属性、公开的方法和事件。
		BeanInfo bin  = 	Introspector.getBeanInfo(Person.class , Object.class);//获取Person属性,方法和事件,不包括Object父类以上类继承来的属性和方法以及事件
		//得到Person类的属性描述器
		PropertyDescriptor[] pros = bin.getPropertyDescriptors();
		//显示Person—Object继承链内的所有属性
		for(PropertyDescriptor pro : pros){
			System.out.println(pro.getName());
		}	//会输出a,age,class,name,password五个属性,class属性来源于继承的父类Object,其他属性的判断根据get方法(必须带返回值)
		}
		
		//操作bean的指定属性:age
		@Test
		public void test2() throws Exception{ 
			Person p = new Person();
			//获取属性描述器
			PropertyDescriptor pd = new PropertyDescriptor("age",Person.class);
			
			//给age属性赋值
			Method  mpd = pd.getWriteMethod();
			mpd.invoke(p, 20); 	//方法执行
			
			//获取age属性的值
			Method mpd2 = pd.getReadMethod();
			int mpd2v = (Integer) mpd2.invoke(p, null);
			System.out.println(mpd2v);
		}
		 
		//获取当前操作的属性的类型
		@Test
		public void test3() throws Exception{
			PropertyDescriptor pd = new PropertyDescriptor("age", Person.class);
			//获取到属性描述器对该属性类型的描述
			if(pd.getPropertyType().equals(int.class)){
				System.out.println(pd.getPropertyType());
			}
		}
}

package 内省introspector;

//内省:什么是javaBean(以下形式称为javabean)
public class Person {

	private String name; // 没有get/set方法称为字段,有get/set方法的称为属性
	private String password;
	private int age;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	// 未声明字段,但是存在set/get方法,此时也是一个属性
	// 以下也是一个属性
	public void setA() {
		
	}
	//共有5个属性,从Object集成一个getClass属性方法
	public String getA() {
		return "aa";
	}
}

BeanUtils工具类的使用:
package 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.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;

//BeanUtil操作bean属性(第三方jar包)
public class BeanUtils操作bean属性 {
	
	//使用BeanUtils操作Bean属性
	@Test
	public void test() throws IllegalAccessException, InvocationTargetException{
		Person p = new Person();
		BeanUtils.setProperty(p, "name", "lj");
		System.out.println(p.getName());
	} 
	
	//BeanUtils的便利体现
	@Test
	public void test2() throws IllegalAccessException, InvocationTargetException{
		//表单提交的数据都是String类型
		String age="23";
		String name="lijun";
		String password = "sdasd";
		
		Person p = new Person();
		
		BeanUtils.setProperty(p, "age", age);	//类型自动转换(只支持8种基本类型)
		BeanUtils.setProperty(p, "name", name);
		BeanUtils.setProperty(p, "password", password);
		
		System.out.println(p.getAge()+","+p.getName()+","+p.getPassword());
	}
	
	//转换器的注册和使用(String转换为Date类型)
	@Test
	public void test3() throws IllegalAccessException, InvocationTargetException{
		String birthday="1990-07-09";
		//Date类型转换
/*		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);	//异常链,e不能丢
					//有异常一定要抛出,通知上一层程序。否则,上一层程序无法获知此程序是否出错,而继续向下执行					
				}
			}
		}, Date.class);*/
		ConvertUtils.register(new DateLocaleConverter(), Date.class);
		Person p = new Person();
		BeanUtils.setProperty(p, "birthday", birthday);//注册Date类型转换器
		System.out.println(p.getBirthday().toLocaleString());
	}
	
	//BeanUtils自动填充数据
	@Test
	public void test4() throws IllegalAccessException, InvocationTargetException{
		//客户端提交的数据
		Map map = new HashMap();
		map.put("name", "李军");
		map.put("birthday", "1999-09-09");
		map.put("password", "sadaqwe");
		map.put("age", "123456");
		//注册Date数据类型转换
		ConvertUtils.register(new Converter() {
			@Override
			public Object convert(Class type, Object value) {
				// TODO Auto-generated method stub
				if(!(value instanceof String)) throw new ConversionException("只能转换String类型数据");
				String str = (String) value;
				if("".equals(str.trim())) return null;
				if(value==null) return null;
				//转换函数
				SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
				try {
					return df.parse(str);
				} catch (ParseException e) {
					// TODO Auto-generated catch block
					throw new RuntimeException(e);
				}//	df.format(date)从Date转到String,parse从String转到Date
			}
		}, Date.class);
		
		//BeanUtils自动填充数据
		Person p = new Person();
		BeanUtils.populate(p, map);
		System.out.println(p.getName()+p.getPassword()+p.getAge()+p.getBirthday().toLocaleString());
	}
	
}

package BeanUtils;

import java.util.Date;

//内省:什么是javaBean(以下形式称为javabean)
public class Person {

	private String name; // 没有get/set方法称为字段,有get/set方法的称为属性
	private String password;
	private int age;
	private Date birthday;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	// 未声明字段,但是存在set/get方法,此时也是一个属性
	// 以下也是一个属性
	public void setA() {
		
	}
	//共有5个属性,从Object集成一个getClass属性方法
	public String getA() {
		return "aa";
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
}






java新特性下

标签:java   泛型   框架   

原文地址:http://blog.csdn.net/u010218226/article/details/42779675

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!