Java 内省、注解、泛型等(系列中)

@version 1.0 2011.01.12

 

 

6,内省(Introspection)、JavaBean
 →JavaBean get/set
  配置文件机制 由类加载器加载,(存放于classpath)

  完整路径(计算 getRealPath()+内部路径完整路径计算 getRealPath()+内部路径)
  //InputStream ips =

       ReflectTest2.class.getClassLoader().

       getResourceAsStream("cn/itcast/day1/config.properties");
  //InputStream ips =

       ReflectTest2.class.getResourceAsStream("resources/config.properties");
  InputStream ips =

       ReflectTest2.class.

       getResourceAsStream("/cn/itcast/day1/resources/config.properties");
  Properties props = new Properties();
  props.load(ips);
  ips.close();
  String className = props.getProperty("className");
 →内省的方法读取类的属性值
  public static void main(String [] args) throws Exception{
  ReflectPoint pt1 = new ReflectPoint(3,5); //JavaBean对象
  String propertyName = "x";
  PropertyDescriptor pd =

       new PropertyDescriptor(propertyName,pt1.getClass());
  Method methodGetX = pd.getReadWrite();
  Object retVal = methodGetX.invoke(pt1);
  
  Method methodSetX = pd.getWriteWrite();
  methodSetX.invoke(pt1,7);
  
  System.out.println(pt1.getX());
  }
 →Eclipse重构
 →BeanUtils (apache)
  getProperty、setProperty
  /* //java7的新特性 
  Map map = {name:"zxx",age:18}; //定义map内容
  BeanUtils.setProperty(map, "name", "lhm"); //对map操作
  */
  PropertyUtils (属性类型不转换)


7,注解 Annotation 

→@SuppressWarnings("deprecation") //编译过滤过时警告
 
→@Deprecated //标记过时
 
→@override  //标记重写
 包、类、成员变量、参数、局部变量都可以注解
 →注解的应用
  @interface A{}
 
  @A
  Class B{}
 
  Class C{
         B.class.isAnnotionPresent(A.class);
         A a = B.class.getAnnotion(A.class);
  }
 →元注解 
 
→@Retention(RetentionPolicy.RUNTIME)——(CLASS/RUNTIME/SOURCE) 
  @Override(SOURCE)、@SuppressWarnings(SOURCE)、@Deprecated(RUNTIME)
 
→@Target(ElementType.METHOD)、

    @Target({ElementType.METHOD,ElementType.TYPE})
 
 →注解的定义的反射调用以及为注解增加属性
 import java.lang.reflect.Method;
 import javax.jws.soap.InitParam;

 @ItcastAnnotation(

       annotationAttr=@MetaAnnotation("flx"),

       color="red",value="abc",arrayAttr=1)
 public class AnnotationTest {

  @SuppressWarnings("deprecation")
  @ItcastAnnotation("xyz")
  public static void main(String[] args) throws Exception{
   System.runFinalizersOnExit(true);
   if(AnnotationTest.class.isAnnotationPresent(ItcastAnnotation.class)){
    //反射调用
    ItcastAnnotation annotation = (ItcastAnnotation)AnnotationTest.class.
                                               getAnnotation(ItcastAnnotation.class);
    //注解属性
    System.out.println(annotation.color());
    System.out.println(annotation.value());
    System.out.println(annotation.arrayAttr().length);
    System.out.println(annotation.lamp().nextLamp().name());
    System.out.println(annotation.annotationAttr().value());
   }
   
   Method mainMethod = AnnotationTest.class.

                                          getMethod("main", String[].class);
   ItcastAnnotation annotation2 = (ItcastAnnotation)mainMethod.
                                                  getAnnotation(ItcastAnnotation.class);
   System.out.println(annotation2.value());
  }
 }
 
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 import cn.itcast.day1.EnumTest;

 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.METHOD,ElementType.TYPE})
 public @interface ItcastAnnotation {
  String color() default "blue";
  String value();
  int[] arrayAttr() default {3,4,4};
  EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.RED;
  MetaAnnotation annotationAttr() default @MetaAnnotation("lhm");
 }

 

8,泛型【36-43】
 →泛型(参数化类型)对于集合类尤其有用,增强可读性、避免频繁强制类型转换和不安全类型转换等;
  泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用。
  eg:Map<String, String> m = new HashMap<String, String>();  //附加的类型安全
 →泛型提供给javac编译器使用,编译完成将去掉泛型信息(运用反射将绕过泛型定义)
 →参数化类型不考虑类型参数的继承关系
 →数组实例创建时,数组的元素不能使用参数化的类型
 →通配符类型(wildcard type)、(extends、super关键字——上边界、下边界)
  “?”代表未知类型,这个类型实现Collection了接口。
  1、如果只指定了<?>,而没有extends,则默认是允许Object及其下的任何Java类了。也就是任意类。
  2、通配符泛型不单可以向下限制,如<? extends Collection>,还可以向上限制,如<? super Double>,
     表示类型只能接受Double及其上层父类类型,如Number、Object类型的实例。
  3、泛型类定义可以有多个泛型参数,中间用逗号隔开,还可以定义泛型接口,泛型方法。
 →泛型方法
  是否拥有泛型方法,与其所在的类是否泛型没有关系。要定义泛型方法,只需将泛型参数列表置于返回值前。
  使用泛型方法时,不必指明参数类型,编译器会自己找出具体的类型。泛型方法除了定义不同,调用就像普通方法一样。
  需要注意,一个static方法,无法访问泛型类的类型参数,所以,若要static方法需要使用泛型能力,必须使其成为泛型方法。
 →eg
 例子一:使用了泛型
  public class Gen<T> {
  private T ob; //定义泛型成员变量
  public Gen(T ob) {
   this.ob = ob;
  }
  public T getOb() {
   return ob;
  }
  public void setOb(T ob) {
   this.ob = ob;
  }
  public void showType() {
   System.out.println("T的实际类型是: " + ob.getClass().getName());
  }
  }
  public class GenDemo {
   public static void main(String[] args){
    //定义泛型类Gen的一个Integer版本
    Gen<Integer> intOb=new Gen<Integer>(88);
    intOb.showType();
    int i= intOb.getOb();
    System.out.println("value= " + i);
    System.out.println("----------------------------------");
    //定义泛型类Gen的一个String版本
    Gen<String> strOb=new Gen<String>("Hello Gen!");
    strOb.showType();
    String s=strOb.getOb();
    System.out.println("value= " + s);
   }
  }
  例子二:没有使用泛型
  public class Gen2 {
  private Object ob; //定义一个通用类型成员
  public Gen2(Object ob) {
   this.ob = ob;
  }
  public Object getOb() {
   return ob;
  }
  public void setOb(Object ob) {
   this.ob = ob;
  }
  public void showTyep() {
   System.out.println("T的实际类型是: " + ob.getClass().getName());
  }
  }
  public class GenDemo2 {
   public static void main(String[] args) {
    //定义类Gen2的一个Integer版本
    Gen2 intOb = new Gen2(new Integer(88));
    intOb.showTyep();
    int i = (Integer) intOb.getOb();
    System.out.println("value= " + i);
    System.out.println("---------------------------------");
    //定义类Gen2的一个String版本
    Gen2 strOb = new Gen2("Hello Gen!");
    strOb.showTyep();
    String s = (String) strOb.getOb();
    System.out.println("value= " + s);
   }
  }
  运行结果:
  两个例子运行Demo结果是相同的,控制台输出结果如下:
  T的实际类型是:
  java.lang.Integer
  value= 88
  ----------------------------------
  T的实际类型是: java.lang.String
  value= Hello Gen!
  Process finished with exit code 0

 →另《java泛型详解》from http://blog.csdn.net/zkdemon/archive/2008/01/14/2043503.aspx
 
 →HashMap、Map.Entry(条目)
   ----------------------------------
  HashMap<String,Integer> maps = new HashMap<String, Integer>();
  maps.put("zxx", 28);
  maps.put("lhm", 35);
  maps.put("flx", 33);
  //HashMap的泛型实际参数类型是一个参数化的类型
  Set<Map.Entry<String,Integer>> entrySet = maps.entrySet();
  for(Map.Entry<String, Integer> entry : entrySet){
   System.out.println(entry.getKey() + ":" + entry.getValue());
  }
  
 →自定义泛型
  private static <T> void swap(T[] a,int i,int j){
   T tmp = a[i];
   a[i] = a[j];
   a[j] = tmp;
  }
  swap(new String[]{"abc","xyz","itcast"},1,2); //交换"xyz"、"itcast"
  //swap(new int[]{1,3,5,4,5},3,4); //报错,泛型的参数类型不能是基本类型,只能是引用类型
  
  →类型推断
  →throws异常使用泛型
  →泛型方法

  ----------------------------------
  private static <T> T autoConvert(Object obj){
   return (T)obj;
  }
  String x3 = autoConvert(obj); //
  ----------------------------------
  private static <T> void fillArray(T[] a,T obj){
   for(int i=0;i<a.length;i++){
    a[i] = obj;
   }
  }
  ----------------------------------
  public static void printCollection(Collection<?> collection){
   //collection.add(1);
   System.out.println(collection.size());
   for(Object obj : collection){
    System.out.println(obj);
   }
  }
  public static <T> void printCollection2(Collection<T> collection,T obj2){
   //collection.add(1);
   System.out.println(collection.size());
   for(Object obj : collection){
    System.out.println(obj);
   }
   collection.add(obj2);
  }
  ----------------------------------
  public static <T> void copy1(Collection<T> dest,T[] src){
   for(int i=0;i<src.length;i++){//拷贝集合到数组
    dest.add(src[i]);
   }
  }
  public static <T> void copy2(T[] dest,T[] src){//拷贝数组到数组
   for(int i=0;i<src.length;i++){
    dest[i] = src[i];
   }
  }
  copy1(new Vector<String>(),new String[10]);
  copy2(new Date[10],new String[10]);  //类型推断Object
  //copy1(new Vector<Date>(),new String[10]); //报错,Vector传播为Date,无法和String再进行类型推断
  
  →类型推断总结【41,12:30】
  
  →泛型类型(类)
  ----------------------------------
  import java.util.Set;
  public class GenericDao<E>  { //crud
   public void add(E x){
   }
   public E findById(int id){
    return null;
   }
   public void delete(E obj){
   }
   public void delete(int id){
   }
   public void update(E obj){
   }
   public static <E> void update2(E obj){
   }
   public E findByUserName(String name){
    return null;
   }
   public Set<E> findByConditions(String where){
    return null;
   }
  }
  ----------------------------------
  GenericDao<ReflectPoint> dao = new GenericDao<ReflectPoint>();
  dao.add(new ReflectPoint(3,3));  
  //String s = dao.findById(1); //类型约束
  
 →通过反射获得泛型的实际类型参数
  //例如webservice返回集合内容未知类型确定,难度是上文所说的“去类型化”,(Hibernate框架实现的方法)。
  ----------------------------------
  public static void applyVector(Vector<Date> v1){ 
  }
  ----------------------------------
  //Vector<Date> v1 = new Vector<Date>(); 
  Method applyMethod = GenericTest.class.

                                        getMethod("applyVector", Vector.class);

  //可以通过返回方法的参数类型获得原泛型类型!
  Type[] types = applyMethod.getGenericParameterTypes(); 

  ParameterizedType pType = (ParameterizedType)types[0];
  System.out.println(pType.getRawType());    //class java.util.Vector
  System.out.println(pType.getActualTypeArguments()[0]); 

                                                               //class java.util.Date
  ----------------------------------
  
 

 

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值