JAVA技术增强

来源:互联网 发布:php高并发解决方案 编辑:程序博客网 时间:2024/06/09 17:35

从一些视频教程和资料中自己了解了一些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技术增强的知识了,更加详细的知识点需要我们查阅相关资料,这也是自己在一边写一边回忆学过的知识大笑大笑


补充:

Introspector方式:

</pre><pre name="code" class="java">//得到bean所有的属性@Testpublic 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某个属性@Testpublic 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某个属性类型@Testpublic 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>@Testpublic void test1() throws IntrospectionException, IllegalAccessException, InvocationTargetException {//为了让日期赋到bean的birthday属性上,我们给beanUtils注册一个日期转换器ConvertUtils.register(new Converter() {@Overridepublic 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());}@Testpublic 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());}@Testpublic 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());}


3 0