黑马程序员:基础加强(可变参数、增强for、枚举、javabBean、BeanUtils、注解、泛型)

------- android培训java培训期待与您交流! ---------- 



==============可变参数(JDK1.5新特性)===================
     可变参数的特点:
      a、只能出现在参数列表的最后;
      b、...位于变量类型和变量名之间,前后有无空格都可以;
      c、调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数。
书写格式:
    可变参数用来代替输入类型相同但是个数不确定是用,下面就是多个数相加的例子。
    一些方法在jdk1.5中用可变参数,在jdk1.4中由于没有可变参数用的是数组表示代替的
[java] view plaincopy
public int add (int i ,int ... args) ;  
 

==================增强for循环(JDK1.5 新特性)============
书写格式:   for ( type变量名:集合变量名) { … }
  注意:
   迭代变量必须在( )中定义!
   集合变量可以是数组或实现了Iterable接口的集合类
用增强for循环遍历一个Integer数组
[java] view plaincopy
Integer[] ins = new Integer[]{2,4,7,48,4} ;  
        for(Integer i : ins){  
            System.out.println(i) ;  
        }  

===========枚举(enum JDK1.5新特性)============
    枚举其实就是一个特殊的类,枚举中的每一个元素(枚举值)都是该类的一个实例对象。
    枚举的出现是为了解决某些类型的值只能是固定的几个中的一个,
    比如:交通灯只有红绿黄三种,一个星期也只有星期一到星期日。
 
枚举的一些特点:
  ·构造函数必须私有
  ·枚举中的每隔元素都private final static的
  ·枚举中方法可以有公有的,也可以有抽象的
 
以下用一个枚举的实例:
[java] view plaincopy
/* 
 * 模拟交通灯的一个枚举类 
 *  
 * 每个灯都有一个方法nextLamp是用于指示下一亮的灯 
 *  
 * */  
public class EnumTest{  
    public static void main(String[] args) {  
        System.err.println("the nextLamp of green is ::"  
                +TrafficLamp.GREEN.nextLamp());  
          
        System.out.println("the nextLamp of yellow is ::"  
                + TrafficLamp.YELLOW.nextLamp());  
          
        System.out.println("the nextLamp of red is ::"  
                + TrafficLamp.RED.nextLamp());  
    }  
      
    public enum TrafficLamp{  
          
        //三个枚举值各自实现了抽象方法  
        RED("RED"){  
            @Override  
            public TrafficLamp nextLamp(){  
                return GREEN;  
            }  
        }  
          
        ,GREEN("GREEN"){  
            @Override  
            public TrafficLamp nextLamp(){  
                return YELLOW;  
            }  
        }  
        ,YELLOW("YELLOW"){  
            @Override  
            public TrafficLamp nextLamp(){  
                return RED;  
            }  
        } ;  
          
        private String lamName ;  
        TrafficLamp(String lamName){  
            this.lamName = lamName ;  
        }  
        //抽象方法,指示下一个亮的灯  
        public abstract TrafficLamp nextLamp() ;  
        public String toString(){  
            return this.lamName ;  
        }  
    }  
}  
      每个枚举值之间是用逗号隔开,最后用分号(如果后面没有内容了也可以不写),
      在枚举值得前面不能再写任何内容了,即枚举值必须写在类的最开头处。
========================内省引出JavaBean的讲解==============
内省主要用于JavaBean的操作
introSpector->JavaBean->特殊的java类,其方法符合某种特殊规则
JavaBean是一种特殊的java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。
如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,
这种JavaBean的实例对象称之为值对象(Value Object,简称VO)。
目的只是传递值,动作方法就没了,这些信息在类中用私有字段存储,如果读取或设置这些字段的值
,则需要通过一些相应的方法来访问,JavaBean的属性是根据setter和getter方法来确定的。

如方法名为getId,中文意思即为获取id,至于你从哪个变量取,不要管。去掉前缀剩余的就是属性名.
如果第二个字母为少写,则把首字母改成小的。
 
============对JavaBean的简单内省操作============
一个符合JavaBean特点的类可以当作普通类来处理,也可以当作JavaBean来操作。
jdk中提供了对JavaBean进行操作的一些API,这套API就称为内省。
 
=========对JavaBean的复杂内省操作===============
get:
PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
              Method methodGetX = pd.getReadMethod();
              Object retVal = methodGetX.invoke(pt1);
set:
PropertyDescriptor pd2 = new PropertyDescriptor(propertyName,pt1.getClass());
              Method methodSetX = pd2.getWriteMethod();
              methodSetX.invoke(pt1,value);
复杂的get:
              BeanInfo beanInfo =  Introspector.getBeanInfo(pt1.getClass());
              PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
              Object retVal = null;
              for(PropertyDescriptor pd : pds){
                     if(pd.getName().equals(propertyName))
                     {
                            Method methodGetX = pd.getReadMethod();
                            retVal = methodGetX.invoke(pt1);
                            break;
                     }
              }
              return retVal;
 
===============使用BeanUtils工具包操作JavaBean=============
添加BeanUtils jar包操作:在工程目录下创建lib文件夹并把jar包复制到这里来,
选择jar包右键选择Build Path->Add to Build Path
同时还要用到日记开发包logging,也增加到Build Path
BeanUtils工具包应用举例:
BeanUtils.getProperty(pt1, "x");
               //已经转换成字符串,不用我们去改,在web开发经常用到。
              BeanUtils.setProperty(pt1, "x", "9");
              //birthday为Date类型,Date().setTime()的属性就是time,所以BeanUtils可以获取更深的属性
               BeanUtils.setProperty(pt1, "birthday.time", "111");
              System.out.println(BeanUtils.getProperty(pt1, "birthday.time"));
PropertyUtils.setProperty(pt1, "x", 9);//不进行类型转换,x还是integer,与BeanUtils形成对比
//java7的新特性
              Map map = {name:"zxx",age:18};
              BeanUtils.setProperty(map, "name", "lhm");


================java5的注解===================

============了解和入门注解的应用===============
注解就是用于告诉开发工具或者是编译器,向它传递某种信息。
一个注解就是一个类。
注解相当于一种标记,在程序中加了注解就等于为程序打了某种标记,以后,javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,去干相应的事。标记可以加在包,类,字段,方法的参数已经局部变量上。
jdk自带的三个注解:@SuppressWarnings(去除警告)  @Deprecated(添加警告) @Override(提示覆盖)
 
================注解的定义与反射调用================
 注解的应用结构:
@interface A{}(注解类)->@A Class B(应用了注解类的类)
->Class C{B.class.isAnnotionPresent(A.class);
A a=B.class.getAnnotion)(A.class)}(对应用注解类的类进行
 反射操作的类)
 
默认时编译器在编译时会去掉注释,所以我们要在注释类中再添加注释让编译器知道这个注释类要保留到运行时
引出@Retention元注释的讲解,有三种取值:
RetetionPolicy.SOURCRE、RetetionPolicy.CLASS、RetetionPolicy.RUNTIMR;
分别对应:java源文件->class文件->内存中的字节码。自定义注释默认值是保留到class阶段
@SuppressWarnings(SOURCRE阶段)  @Deprecated(RUNTIMR阶段)
@Override(SOURCRE阶段)
设置注释可以保留到哪个阶段:@Retention(RetentionPolicy.RUNTIME)
设置注释能够加到什么类型身上:@Target({ElementType.METHOD,ElementType.TYPE})
TYPE是class、enum等的更高层次即父类
 

=============为注解增加各种属性================
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");//注释类型属性
}
应用:
@ItcastAnnotation(annotationAttr=@MetaAnnotation("flx"),color="red",value="abc",arrayAttr=1)
class AnnotationTest{}
调用:
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());
              }


================java5的泛型===================


=========入门泛型的基本应用===========
 泛型应用 ArrayList后加<String>说明这个是String类型的
ArrayList<String> collection2=new ArrayList<String>();
collection2.add("abc");
STring element=collection2.get(1); //不用类型转换了
 总结:没用泛型时,不管什么类型的对象都可以存储进同个集合,使用泛型集合可以将集合的元素限定为特殊类型,
这样更安全,同时获取它时不需要对对象进行强制类型转换
 

===========泛型的内部原理及更深应用=============
 泛型编译后类型信息会被去掉(去类型化)
应用:可以用反射透过编译器在其中加入其他类型数据
如:collection3.getClass().getMethod("add",Object.class).invoke(collection3,"abc");
system.out.println(collection3.get(0));
 
泛型术语
如ArrayList<E>的E称为类型变量或类型参数
而ArrayList<Integer>的integer称为类型参数的实例。<>念typeof
 ArrayList称为原始类型
参数化类型与原始类型的兼容性
//可不可以还不是编译器的一句话的事
参数化类型不考虑类型参数的继承关系
 

==============泛型的通配符扩展应用===================
<? > 使用?通配符可以引用其他各种参数化类型,?通配符主要是作为引用,可以调用参数无关的方法,不能调用参数化有关的方法
collection.size()
<? extends  >?通配符的扩展
extends 限定通配符的上边界
super 限定通配符的下边界
 

===============泛型集合的综合应用案例=================
Map->Set,然后进行迭代
HashMap<String,Integer> maps = new HashMap<String, Integer>();
              maps.put("zxx", 28);
              maps.put("lhm", 35);
              maps.put("flx", 33);
              Set<Map.Entry<String,Integer>> entrySet = maps.entrySet();
              for(Map.Entry<String, Integer> entry : entrySet){
                     System.out.println(entry.getKey() + ":" + entry.getValue());
              }
 

==============自定义泛型方法及其应用==================
类型推断,返回xy的交集:
private static<T> T add(T x,T y)
                add(3,5);
              Number x1 = add(3.5,3);
              Object x2 = add(3,"abc");
 
引用不能是基本数据类型:
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);
//swap(new int[]{1,3,5,4,5},3,4);T的引用不能是基本数据类型(int)
 

================自定义泛型方法的练习与类型推断总结=================
 实现自动将Object类型的对象转换成其他类型:
private static <T> T autoConvert(Object obj){
              return (T)obj;
       }
Object obj = "abc";
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){
              System.out.println(collection.size());
              for(Object obj : collection){
                     System.out.println(obj);
              }
       }
      
       public static <T> void printCollection2(Collection<T> collection){
              System.out.println(collection.size());
              for(Object obj : collection){
                     System.out.println(obj);
              }
       }
定义一个方法,把任意参数类型的集合中的数据安全的复制到相应类型的数组中:
public static <T> void copy1(Collection<T> dest,T[] src){
             
       }
      
       public static <T> void copy2(T[] dest,T[] src){
             
       }
 
copy1(new Vector<String>(),new String[10]);
              copy2(new Date[10],new String[10]);//取交集即Object          
              //copy1(new Vector<Date>(),new String[10]);出错,泛型具有传播性,既然<Date>已经确定,<T>也就确定为<Date>了。
 
泛型方法的定义:只要在返回值之前用<T>来说明类型即可
 

===================自定义泛型类的应用=================
 在类身上定义泛型
 
public class GenericDao<E>  {
       public void add(E x){   
       }
       public E findById(int id){
              return null;
       }
}


===================通过反射获得泛型的实际类型参数==============
得到方法的参数的实际类型
public static void applyVector(Vector<Date> v1){
       }
Method applyMethod = GenericTest.class.getMethod("applyVector", Vector.class);
              Type[] types = applyMethod.getGenericParameterTypes();
              ParameterizedType pType = (ParameterizedType)types[0];
              System.out.println(pType.getRawType());
              System.out.println(pType.getActualTypeArguments()[0]);

------- android培训java培训期待与您交流! ---------- 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值