---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! -----------------------
1. JavaBean
1.1、 一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。JDK中提供了对JavaBean进行操作的一些API,这套API就称为内省。
1.2、 得到BeanInfo最好采用“obj.getClass()”方式,而不要采用“类名.class”方式,这样程序更通用。
1.3、 复杂的內省操作:采用遍历BeanInfo的所有属性方式来查找和设置某个RefectPoint对象的x属性。在程序中把一个类当作JavaBean来看,就是调用IntroSpector.getBeanInfo方法, 得到的BeanInfo对象封装了把这个类当作JavaBean看的结果信息。
1.4、 BeanUtils工具包
BeanUtils.setProperty(pt1, "x", "1"); //此处的value “1”可以使用String,也可使用Integer
BeanUtils.getProperty(pt1, "x"); //返回值类型为String
get属性时返回的结果为字符串,set属性时可以接受任意类型的对象,通常使用字符串。
PropertyUtils.setProperty(pt1, "x", 1); //只能使用与x类型对应的类型进行设置
PropertyUtils.getProperty(pt1, "x"); //返回值类型为属性x的类型
get属性时返回的结果为该属性本来的类型,set属性时只接受该属性本来的类型。
BeanUtils支持属性的级延操作,如pt1有一个birthday(private Date birthday = new Date();)属性,而DAte类的setTime()方法符合JavaBean的命名规则,可以使用如
下的方式进行time的操作:
BeanUtils.setProperty(pt1, "birthday.time", 111);
BeanUtils.getProperty(pt1, "birthday.time");
1.5、 java7新特性
Map map = {name : "xxx", age : 12};
BeanUtils.setProperty(map, "age", 111);
2. Annotation
2.1、 注解的应用结构
注解类-->应用了注解类的类-->对“应用了注解类的类”进行反射操作的类
2.2、
@Retention(RetentionPolicy.RUNTIME)//元注解(还有元数据、元信息等)
@Target({ElementType.TYPE,ElementType.METHOD})//用于说明注解可以用在哪些成分上
public @interface MyAnnotation {
String color() default "blue";
String value();
int[] arrayAttr() default {1,2};
EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.RED;
MetaAnnotation annotationAttr() default @MetaAnnotation("zxx");
Class clazz() default String.class;
}
(1)@Retention(RetentionPolicy.RUNTIME)//元注解(还有元数据、元信息等),该语句用于设定注解类的生命周期,
RetentionPolicy是一个枚举类,有3个元素,SOURCE,CLASS,RUNTIME,分别对应:java源文件-->class文件-->内存中的字节码。默认值为CLASS.
(2)@Override、@SuppressWarnings和@Deprecated这三个注解的属性值分别是什么?SOURCE,SOURCE,RUNTIME
(3)@Target({ElementType.TYPE,ElementType.METHOD})//用于说明注解可以用在哪些成分上
ElementType.TYPE:这里用的是type,type是class的父类,class只是java类的一种,用type比class更精准
ElementType的值有以下几种:
ANNOTATION_TYPE,CONSTRUCTOR,FIELD,LOCAL_VARIABLE,METHOD,PACKAGE,PARAMETER,TYPE
(4)注解的属性,可以设定默认值,如果在使用时只有一个属性需要进行设定,在使用时可以直接填写属性值,而不用写“属性=属性值的方式”;对应数组属性,如果只有一个数组元素,可以不用“{}”;属性值除了默认值外,也可以在使用时重新设定
3. 泛型 generic idk1.5出现的安全机制
3.1、(1)泛型将运行时期的问题ClassCAstException转到了编译时期,也避免了前置转换的麻烦;
在JDK 1.5中,你还可以按原来的方式将各种不同类型的数据装到一个集合中,但编译器会报告unchecked警告
(2)编译器编译带类型说明的集合时会去除掉“类型”信息,使程序运行效率不受影响,对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一样。
(3)由于编译生成的字节码会去掉泛型的类型信息,只要能跳过编译器,就可以往某个泛型集合中加入其它类型的数据,例如,用反射得到集合,再调用其add方法即可。
3.2、ArrayList<E>类定义和ArrayList<Integer>类引用中涉及如下术语:
整个称为ArrayList<E>泛型类型
ArrayList<E>中的E称为类型变量或类型参数
整个ArrayList<Integer>称为参数化的类型
ArrayList<Integer>中的Integer称为类型参数的实例或实际类型参数
ArrayList<Integer>中的<>念着typeof
ArrayList称为原始类型
3.3、参数化类型与原始类型的兼容性
参数化类型不考虑类型参数的继承关系
编译器不允许创建泛型变量的数组。即在创建数组实例时,数组的元素不能使用参数化的类型,例如,下面语句有错误:
Vector<Integer> vectorList[] = new Vector<Integer>[10];
但是下面的代码不会报错:Vector v1 = new Vector<String>(); Vector<Object> v = v1;
3.4、使用?通配符可以引用其他各种参数化的类型,?通配符定义的变量主要用作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。
限定通配符总是包括自己。?只能用作引用,不能用它去给其他变量赋值
下面的代码错误,原理与Vector<Object > v = new Vector<String>();相似,只能通过强制类型转换方式来赋值。
Vector<? extends Number> y = new Vector<Integer>();
Vector<Number> x = y;
3.5、泛型方法
(1)只有引用类型才能作为泛型方法的实际参数,swap(new int[3],3,5);语句会报告编译错误。
(2)除了在应用泛型时可以使用extends限定符,在定义泛型时也可以使用extends限定符,例如,Class.getAnnotation()方法的定义。并且可以用&来指定多个边界, 如
<V extends Serializable & cloneable> void method(){}
(3)普通方法、构造方法和静态方法中都可以使用泛型。
(4)也可以用类型变量表示异常,称为参数化的异常,可以用于方法的throws列表中,但是不能用于catch子句中。
如:try{...}catch(Exception e){throw (T)e} // 不能将Exception改为T
(5)在泛型中可以同时有多个类型参数,在定义它们的尖括号中用逗号分,例如:public static <K,V> V getValue(K key) { return map.get(key);}
3.6、类型推断-->编译器判断范型方法的实际类型参数的过程称为类型推断
根据调用泛型方法时实际传递的参数类型或返回值的类型来推断,具体规则如下:
(1)当某个类型变量只在整个参数列表中的所有参数和返回值中的一处被应用了,那么根据调用方法时该处的实际应用类型来确定,这很容易凭着感觉推断出来,即直接根据调用方法时传递的参数类型或返回值来决定泛型参数的类型,例如:
swap(new String[3],3,4) --> static <E> void swap(E[] a, int i, int j)
(2)当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型都对应同一种类型来确定,这很容易凭着感觉推断出来,例如:
add(3,5) --> static <T> T add(T a, T b)
(3)当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型对应到了不同的类型,且没有使用返回值,这时候取多个参数中的最大交集类型,例如,下面语句实际对应的类型就是Number了,编译没问题,只是运行时出问题:
fill(new Integer[3],3.5f) --> static <T> void fill(T[] a, T v)
(4)当某个类型变量在整个参数列表中的所有参数和返回值中的多处被应用了,如果调用方法时这多处的实际应用类型对应到了不同的类型,并且使用返回值,这时候优先考虑返回值的类型,例如,下面语句实际对应的类型就是Integer了,编译将报告错误,将变量x的类型改为float,对比eclipse报告的错误提示,接着再将变量x类型改为Number,则没有了错误:
int x =(3,3.5f) --> static <T> T add(T a, T b)
(5)参数类型的类型推断具有传递性,下面第一种情况推断实际参数类型为Object,编译没有问题,而第二种情况则根据参数化的Vector类实例将类型变量直接确定为String类型,编译将出现问题:
copy(new Integer[5],new String[5]) --> static <T> void copy(T[] a,T[] b);
copy(new Vector<String>(), new Integer[5]) --> static <T> void copy(Collection<T> a , T[] b);
3.7、泛型类
dao-->data access object-->crud
(1)当一个变量被声明为泛型时,只能被实例变量、方法和内部类调用,而不能被静态变量和静态方法调用。因为静态成员是被所有参数化的类所共享的,所以静态成员不应该有类级别的类型参数。
(2)类中只有一个方法需要使用泛型,是使用类级别的泛型,还是使用方法级别的泛型?
3.8、通过反射获得泛型的实际类型参数
public class GenericParameter {
public static void main(String[] args) throws Exception {
Method method = GenericParameter.class.getMethod("applyVector", Vector.class);
Type[] types = method.getGenericParameterTypes();
ParameterizedType type = (ParameterizedType)types[0];
System.out.println(type.getRawType());
System.out.println(type.getActualTypeArguments()[0]);
}
public static void applyVector(Vector<Date> v){
}
}
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! -----------------------