天天看点

JAVA技术增强

从一些视频教程和资料中自己了解了一些JAVA技术增强的知识,写进博客,留下些笔记:

1、Jnuit测试

@Test

@BeforeClass(类加载时运行,方法必须是为static) @AfterClass(类加载时运行,方法为static)

@Before(方法运行前运行,方法不能使静态方法) @After(方法运行后运行,方法不能使静态方法)

Assert属于单元测试中的一个类,其中有很多的方法可以满足测试

Assert.Method() 断言(期望值与返回值是否相同得到方法测试是否通过)

2、Java 5.0新特性

1)静态导入 import static java.lang.System.out;  程序中可以这样使用:out.println("");

2)自动拆箱装箱 Integer i = 1;//装箱 int j = i; //拆箱

  例子: List list = new ArrayList();

list.add(new Integer(1));//无自动拆箱装箱

list.add(2); //自动拆箱装箱

3)增强for循环 只能用在数组、或实现Iterable接口的集合类上(只适合取数据)

4)可变参数 

public void sum(int ...nums){

//可变参数把它看做数组

int sum = 0;

(int i : nums){

sum += i;

}

System.out.println(sum);

} //调用 sum(1, 2, 3), sum(1, 2, 3, 4, 5)

//注意:可变参数要放到其他不变参数的后面

int nums[] = {1, 2, 3};

List list = Arrays.asList(nums);//可变参数

System.out.println(list);//细节注意,当数组是基本数据类型是,nums会作为一个对象

5)枚举

1)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();

}//等同于

enum Grade{

A, B, C, D;//可以定义构造函数,字段,方法等等,它就是个特殊形式的java类

//但是构造函数必须是私有的,枚举就是为了解决限定一定范围的值,即不可以再让他人创建对象

}

//注意:如果枚举类中含有有参数的构造函数,需要使用有参数的构造函数声明,如A("100-90")

2)抽象枚举:即枚举类中含有抽象方法,则创建枚举对象是要实现抽象方法,如:

A("100-90"){

public void 抽象方法(){}

}

3)//枚举类中只有一个值,相当于使用单态模式定义出了一个类

4)//枚举类均是继承了java.lang.Enum类的孩子

//继承的方法:name()(返回名字) ordinal()(返回序号)

//valueOf(Grade.class, "B") (返回字符串是枚举值中的枚举对象,如果不是,会报异常)

//values()返回枚举类的所有的枚举值

3、反射

加载类,并解剖出类的各个组成部分

注意:

1)静态方法调用不用对象,method.invoke(null, 参数)

2)调用main方法

调用main方法

public void test() throws Exception{

Class clazz = Class.forName("");

Method method = clazz.getMethod("main", String[].class);

method.invoke(null,new Object[]{new String[]{"aa","bb"}});

//JDK升级兼容

//jdk1.5 Method.invoke(Object obj,Object...args);

//jdk1.4 Method.invoke(Object obj,Object obj[]);

//jdk1.4 Method.invoke(Object obj,Object obj[]{"ss", "bb");

//相当于Method.invoke(Object obj,String a,String b);为了保证兼容,会把数组拆分

//故写成new Object[]{new String[]{"aa","bb"}}或者(Object)new String[]{"aa","bb"}

//当使用反射时,若参数为数组,注意上述问题

}

4、内省

开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以sun公司开发了一套API,专门用于操作java对象的属性

Introspector-BeanInfo-PropertyDescriptor[]或者PropertyDescriptor

BeanUtils apache开发(commons-beanutils包)

5、泛型

1)Map<K,V> K和V必须是对象类型,即必须是引用类型

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

ArrayList list = new ArrayList<String>();//为保证兼容这样可以,但是两边均有泛型,则两边必须一样

3)泛型提供给javac编译器使用的,它用于限定集合的输入类型,让编译器在源代码级别上,即挡住向集合中插入非法数据。但编译器编译完带有泛型的java程序后,生成的class文件中不在带有泛型信息,以此使程序中运行效率不受到影响,这个过程称之为“擦除”

4)泛型方法

public <T> T a(T t){} //调用a("aaa")

public <T, E, K> void b(T t, E e, K k){}

public class Demo<T>{} //在类上声明泛型,则整个类都有效,但是对于静态方法要重新声明

5)泛型的基本术语,以ArrayList<E>为例

ArrayList<E>中的E称为类型参数变量

ArrayList<Integer>中的Integer称为实际类型参数

整个称为ArrayList<E>泛型类型

整个ArrayList<E>称为参数化的类型ParameterizedType

6)类上声明泛型典型应用

1- //使用到了Hibernate

public class BaseDao<T> {

private Session session;

private Class clazz;

public BaseDao(Class clazz) {

this.clazz = calzz;

}

public void add(T t) {

session.save(t);

}

public T find(String id) {

return (T) session.get(clazz,id);

}

public void update(T t) {

session.update(t);

}

public void delete(String id) {

T t = (T) session.get(clazz,id);

session.delete(t);

}

}

2- //写一个dao继承BaseDao

public class BookDao extends BaseDao<Book> {

public BookDao () {

super(Book.class);

}

//自动拥有了增删改查方法

}

更优雅的设计:

1- public class BaseDao<T> {

private Session session;

private Class clazz;

public BaseDao(){

ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();//BaseDao<Category>//得到参数化类型,如:BaseDao<class>

clazz = (Class) pt.getActualTypeArguments()[0];

}

public void add(T t) {

session.save(t);

}

public T find(String id) {

return (T) session.get(clazz,id);

}

public void update(T t) {

session.update(t);

}

public void delete(String id) {

T t = (T) session.get(clazz,id);

session.delete(t);

}

}

2- //写一个dao继承BaseDao

public class BookDao extends BaseDao<Book> {

//自动拥有了增删改查方法

}

7)通配符

1-<?>使用了问号 通配符,就不能调用与泛型相关(带泛型的方法)的方法

2-<? extends Number>则实际参数类型只能是Number的子类(限定处理类型)

2-<? super Integer>则实际参数类型只能是Integer>的父类(限定处理类型)

以上是Java技术增强的粗略知识框架,好多也都是易错的东西,按照这个知识框架展开,就可以基本掌握Java技术增强的知识了,更加详细的知识点需要我们查阅相关资料,这也是自己在一边写一边回忆学过的知识

JAVA技术增强
JAVA技术增强

补充:

Introspector方式:

</pre><pre name="code" class="java">//得到bean所有的属性
	@Test
	public void test1() throws IntrospectionException {
//		BeanInfo info = Introspector.getBeanInfo(Person.class);
		BeanInfo info = Introspector.getBeanInfo(Person.class, Object.class);//得到bean自己的属性
		PropertyDescriptor[] pds = info.getPropertyDescriptors();
		for(PropertyDescriptor pd : pds) {
			System.out.println(pd.getName());
		}
	}
	
	//操纵bean某个属性
	@Test
	public void test2() throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		Person p = new Person();
		PropertyDescriptor pd = new PropertyDescriptor("age",Person.class);
		Method method = pd.getWriteMethod();
		method.invoke(p, 45);
		Method method1 = pd.getReadMethod();
		System.out.println(method1.invoke(p, null));
	}
	
	//得到bea某个属性类型
	@Test
	public void test3() throws IntrospectionException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
		Person p = new Person();
		PropertyDescriptor pd = new PropertyDescriptor("age",Person.class);
	
		System.out.println(pd.getPropertyType());
	}
           

beanUtils方式:

<span style="white-space:pre">	</span>@Test
	public void test1() throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		
		//为了让日期赋到bean的birthday属性上,我们给beanUtils注册一个日期转换器
		ConvertUtils.register(new Converter() {


			@Override
			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 sdf = new SimpleDateFormat("yyyy-MM-dd");
				try {
					return sdf.parse(str);
				} catch (ParseException e) {
					throw new RuntimeException(e);
				} catch (java.text.ParseException e) {
					e.printStackTrace();
				}
				return sdf;
			}
			
		}, Date.class);
		
		Person p = new Person();
		BeanUtils.setProperty(p, "name", "jack");
		BeanUtils.setProperty(p, "age", "34");//自动转换,但是只支持八种基本数据类型
		
		BeanUtils.setProperty(p, "birthday", "1993-06-01");//需要注册转换器
		
		System.out.println(p.getName());
		System.out.println(p.getAge());
		System.out.println(p.getBirthday());
	}
	
	@Test
	public void test2() throws IntrospectionException, IllegalAccessException, InvocationTargetException {
		
		//为了让日期赋到bean的birthday属性上,我们给beanUtils注册一个日期转换器
		ConvertUtils.register(new DateLocaleConverter(), Date.class);
		
		Person p = new Person();
		BeanUtils.setProperty(p, "name", "jim");
		BeanUtils.setProperty(p, "age", "34");//自动转换,但是只支持八种基本数据类型
		
		BeanUtils.setProperty(p, "birthday", "1993-06-01");//需要注册转换器
		
		System.out.println(p.getName());
		System.out.println(p.getAge());
		System.out.println(p.getBirthday());
	}
	
	@Test
	public void test3() throws IllegalAccessException, InvocationTargetException {
		Map map = new HashMap();
		map.put("name", "aaa");
		map.put("password", "123");
		map.put("age", "23");
		map.put("birthday", "2000-02-01");
		
		ConvertUtils.register(new DateLocaleConverter(), Date.class);
		
		Person bean = new Person();
		BeanUtils.populate(bean, map);
		
		System.out.println(bean.getName());
		System.out.println(bean.getAge());
		System.out.println(bean.getBirthday());
	}