1.JavaBean
/*
* 是一种特殊的类
* int getAge()和void setAge(int age)符合这种规则的类
* 即有get和set的就是javabean
* javabean属性名就是去掉set和get后的那个字母,如过其
* 第二个字母是小写,就把第一个字母也变小写,如果第二个是
* 大写,第一个也是大写
* 如过两个模块之间传递多个信息 ,可以把这些信息封装到一个javabean中
*/
1.1 简单的JavaBean例子
1: package Itcast.com;
2:
3: class JavaBn
4: {
5: private int x;
6: public int y;
7: public JavaBn(int x,int y)
8: {
9: this.x=x;
10: this.y=y;
11: }
12: public int getX() {
13: return x;
14: }
15: public void setX(int x) {
16: this.x = x;
17: }
18:
19:
20:
21:
22: //右键在source里有为x,y添加javabean的快捷方式
23:
24: }
1.2 利用javabean内省的方式来设置(set方法)javaBn中x的属性
1: package Itcast.com;
2:
3:
4: import java.beans.PropertyDescriptor;
5: import java.lang.reflect.InvocationTargetException;
6: import java.lang.reflect.Method;
7:
8:
9:
10: //利用javabean内省的方式来读取(get方法)javaBn中x的属性
11: public class JavaBeanTest
12: {
13: public static void main(String[] args) throws Exception
14: {
15: JavaBn jb=new JavaBn(3,5);
16: String propertyName="x";
17: //PropertyDescriptor属性描述符
18: //把jb类当作javabean来看,从他身上获得属性propertyName,赋予对象pd
19: PropertyDescriptor pd=new PropertyDescriptor(propertyName,jb.getClass());
20: //获得属性后,再用属性提取get或set方法
21: Method methodGetX =pd.getReadMethod();
22: //获得get方法后将其实例化,传入一个对象,以获取方法结果
23: Object retVal=methodGetX.invoke(jb);
24: System.out.println(retVal);
25:
26: //利用javabean内省的方式来设置(set方法)javaBn中x的属性
27:
28: Object value=7;
29: setProperty(jb, pd, value);
30: }
31: //利用重构来抽取方法,可以把重复性的代码提取出来成为共享方法
32: private static void setProperty(JavaBn jb, PropertyDescriptor pd,
33: Object value) throws IllegalAccessException,
34: InvocationTargetException {
35: Method methodSetX =pd.getWriteMethod();
36: methodSetX.invoke(jb,value);
37: System.out.println(jb.getX());
38: }
39: }
2.注解
/**
* 什么是注解?
*注解的生命周期RetentionPolicy.XXX
*默认的生命值只保留在.CLASS中,其他类调用是无效的
*.SOURCE和.RUNTIME
*@Override重载是在.SOURCE时期,他是给javac看的,在编译期,源代码阶段有用
*@SuppressWarmings给编译期用的,也是在.SOURCE时期
*@Deprecated在.RUNTIME时期,要运行了才知道,扫描二进制
*一个注解相当于一个胸牌,为区分注解,需要注解属性
*/
2.1 自定义注解
1: package Itcast.com;
2: import java.lang.annotation.*;
3: /*
4: 元注解
5: 元数据
6: 元信息
7: */
8: //加一个运行时效注解,即该注解在运行期间都有效,超越class阶段
9: @Retention(RetentionPolicy.RUNTIME)
10: //在方法上和类上都可以加target注解,TYPE是CLASS的父类:
11: @Target({ElementType.METHOD,ElementType.TYPE})
12: public @interface ItcastAnnotation
13: {
14: //注解的属性
15: String color() default "blue";//设置color的缺省属性是蓝色
16: String value();
17: //数组类型的属性
18: int[]arrayAttr() default {3,4,5};
19: //枚举类型的属性
20: EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.RED ;
21: //注解类型的属性,缺省值就是他的实际对象
22: MetaAnnotation annotationAttr() default @MetaAnnotation("1hm");
23:
24: }
2.2注解演示
1: package Itcast.com;
2:
3: import java.lang.annotation.Annotation;
4:
5: /**
6: * 什么是注解?
7: */
8: //如果数组中只有一个元素,则可以省略大括号
9: @ItcastAnnotation(annotationAttr=@MetaAnnotation("flx"),color="red",value="abc",arrayAttr=2)//带属性的注解.用的时候自定义属性值
10: public class AnnotationTest
11: {
12: //"deprecation"是一个特殊的注解属性,可以省略名称等号,因为他只有这一个属性
13: @SuppressWarnings("deprecation")//向编译器传递信息,不要再提示过时
14: @ItcastAnnotation("xyz")//color设置了两组缺省值,所以这里这样是可以的
15: public static void main(String[] args)
16: {
17: System.runFinalizersOnExit(true);//过时的
18: //得到你在类上加的注释:
19: if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class))
20: {
21: ItcastAnnotation annotation =(ItcastAnnotation)AnnotationTest.class.getAnnotation(ItcastAnnotation.class);
22: System.out.println(annotation.color());
23: System.out.println(annotation.value());
24: System.out.println(annotation.arrayAttr());
25: //显示枚举类型属性值
26: System.out.println(annotation.lamp());
27: //显示注解类型的属性值
28: System.out.println(annotation.annotationAttr().value());
29: }
30: }
31: @Deprecated//加了这句话后下面的方法自动过时
32: public static void sayHello()
33: {
34: System.out.println("旧的方法,要删除");
35: }
36: //@Override 注解,自动判断你下面的函数是否是覆盖,用于判断自己是否写对了,与重载区分。
37: /*
38: * 注解类--->应用了注解类的类--->对应用了注解类的类进行反射操作的类
39: *
40: */
41: }
3.泛型
/**
* 没有使用泛型时,只要是对象,不管是什么类型的对象,都可以存储
* 进同一个集合中,使用泛型集合,可以将一个集合中的元素限定为
* 一个特定类型,集合中织女呢个存储同一个类型的对象,更安全
* 获取时,编译器也可以知道元素类型,不需要强制类型转换
* 泛型只是提供给编译器使用,以挡住非法输入,编译器在编译已经审查放进来
* 的集合时会去掉类型信息,使程序运行效率不受影响。
* 运行的时候就不知道 元素的类型了
* 因此,跳过编译后用反射方式把已加入的元素类型改掉,也是可以的
* 参数化类型不考虑类型参数的继承关系,必须一致,或者右边缺省泛型,除此外不一致就不行,传不进去
* 泛型中的通配符限定:
* 上边界:<? extends Number>仅限于Number和其子类,number是顶
* 下边界:<? super Integer>仅限于Interger和其父类,Integer是底
*/
1: package Itcast.com;
2: import java.lang.reflect.Method;
3: import java.lang.reflect.ParameterizedType;
4: import java.net.Proxy.Type;
5: import java.sql.Date;
6: import java.util.ArrayList;
7: import java.util.Collection;
8: import java.util.HashMap;
9: import java.util.Map;
10: import java.util.Set;
11: import java.util.Vector;
12:
13:
14: //泛型
15: public class GenericTest
16: {
17: public static void main(String[] args) throws Exception
18: {
19: //解决类型繁多,只接受一个类型
20: ArrayList<String> collection1 =new ArrayList<String>();
21: //collection1.add(1);
22: //collection1.add(1L);//长整数
23: collection1.add("abc");
24: //取出来的都转为整数
25: //int i= (Integer)collection1.get(1);这句编译不通过,因为返回类型不统一,无法都转为一个类型
26: //String element=collection1.get(1);
27: //用反射的方法 向<Integer>集合里加入字符串的 元素,骗过了泛型审查
28: ArrayList<Integer> collection2 =new ArrayList<Integer>();
29: collection2.getClass().getMethod("add",Object.class).invoke(collection2,"abc");
30: System.out.println(collection2.get(0));
31:
32: //泛型中的通配符:?
33: priColl(collection2);//利用通配符成功打印其中的各个元素
34:
35: //泛型的嵌套,用途1:用来遍历取出Map集合的元素
36: HashMap<String,Integer> maps=new HashMap<String,Integer>();
37: maps.put("lsk", 25);
38: maps.put("ssk", 35);
39: maps.put("ksk", 45);
40: Set<Map.Entry<String,Integer>> entrySet=maps.entrySet();
41: //对该集合进行迭代取值
42: for(Map.Entry<String,Integer> entry :entrySet)
43: {
44: System.out.println(entry.getKey()+entry.getValue());
45: }
46: System.out.println(add(3,5.4));
47: //交换数组第1个和第2个元素的位置
48: sawp(new String[]{"abc","xyz","123"},1,2);
49: GenericDao<ReflactPoint> dao = new GenericDao<ReflactPoint>();
50: //dao.add(new ReflactPoint(3,3));
51:
52:
53: /**
54: * 用反射的方式得到Vector里面到底装的是什么类型数据
55: */
56: //Vector<Date> v1=new Vector<Date>();无法得到
57: //1.根据方法名(applyVector)获得使用Vector的方法的字节码文件
58: Method applyMethod = GenericTest.class.getMethod("applyVector", Vector.class);
59: //2.通过getGenericParameterTypes()得到这个方法的参数列表中所有的泛型化了的参数类型,赋给数组types
60: java.lang.reflect.Type[] types= applyMethod.getGenericParameterTypes();
61: //3.只取这个元素为参数类型的数组的第一个元素(因为这里就只有一个Vector)
62: ParameterizedType pType=(ParameterizedType)types[0];
63: //打印一下看看结果
64: System.out.println(pType.getRawType());
65: //得到这个方法参数类型的泛型里面到底装入的是什么类型(只看第一个)
66: System.out.println(pType.getActualTypeArguments()[0]);
67: }
68: public static void applyVector(Vector<Date> v1)
69: {
70:
71: }
72: private static<T> T add(T x,T y)
73: {
74: /**
75: * 类型推断,返回值类型是x与y类型的最大公约数
76: */
77: return y;
78: }
79: //只有引用类型才能作为泛型的实际参数,基本类型不可以
80:
81: //交换数组T第i个和第j个元素的位置
82: private static <T> void sawp(T [] a,int i, int j)
83: {
84: T tmp =a[i];
85: a[i] = a[j];
86: a[j] = tmp;
87: }
88: //通配符定义的变量可以指向其他任意参数化的类型
89: public static void priColl(Collection<?> collection)
90: {
91: System.out.println(collection.size());
92: for(Object obj:collection)
93: {
94: System.out.println(obj);
95: }
96: }
97:
98: }