zoukankan      html  css  js  c++  java
  • 黑马程序员——【Java高新技术】——JavaBean、注解

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

    一、JavaBean

      * 通过内省引入JavaBean:内省对应的英文全程是IntroSpector。在Java中,其作用主要针对JavaBean进行操作。

      (一)概述

      (1)JavaBean是一种特殊的Java类,主要用于传递数据信息,这种Java类中的方法主要用于访问私有的字段,且方法符合某种特殊的命名规则。

      (2)如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO)

      (3)JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。

      如方法名为setId,则中文意思是设置Id,getId也是如此;去掉set或者get前缀,剩余部分就是属性名称。如果剩余部分的第二个字母小写,则把剩余部分改为小写。如:

      Ø getAge/setAge-->age;

      Ø gettime-->time;

      Ø setTime-->time;

      Ø getCPU-->CPU;

      总之,一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。

      (二)JavaBean好处

      符合JavaBean特点的类可以当作普通类一样使用,把它当JavaBean用会带来一些额外的好处:

      1、在Java EE开发中,经常要使用到JavaBean,很多环境就要求按JavaBean方式进行操作。

      2、JDK中提供了对JavaBean进行操作的一些API,这套API就称为内省。用内省这套api操作JavaBean比用普通类的方式更方便。

      (三)内省的简单操作

     

     1 import java.beans.BeanInfo;
     2 import java.beans.IntrospectionException;
     3 import java.beans.Introspector;
     4 import java.beans.PropertyDescriptor;
     5 import java.lang.reflect.InvocationTargetException;
     6 import java.lang.reflect.Method;
     7 import java.util.Map;
     8 import org.apache.commons.beanutils.BeanUtils;
     9 import org.apache.commons.beanutils.PropertyUtils;
    10 public class IntroSpectorTest {
    11     public static void main(String[] args) throws Exception {
    12         ReflectPoint pt1 = new ReflectPoint(3,5);
    13         String propertyName = "x";        
    14         Object retVal = getProperty(pt1, propertyName);    
    15         Object value = 7;        
    16         setProperties(pt1, propertyName, value);
    17         System.out.println(pt1.getX());
    18     }
    19     private static void setProperties(Object pt1, String propertyName,
    20             Object value) throws IntrospectionException,
    21             IllegalAccessException, InvocationTargetException {
    22         PropertyDescriptor pd2 = new PropertyDescriptor(propertyName,pt1.getClass());
    23         Method methodSetX = pd2.getWriteMethod();
    24         methodSetX.invoke(pt1,value);
    25     }
    26     private static Object getProperty(Object pt1, String propertyName)
    27             throws IntrospectionException, IllegalAccessException,
    28             InvocationTargetException {
    29         PropertyDescriptor pd = new PropertyDescriptor(propertyName,pt1.getClass());
    30         Method methodGetX = pd.getReadMethod();
    31         Object retVal = methodGetX.invoke(pt1);
    32         return retVal;
    33     }
    34 }

      (四)对JavaBean的复杂内省操作

      1、操作步骤:

      (1)在IntroSpector类中有getBeanInfo(Class cls)的方法,通过此方法获取BeanInfo实例。参数是相应对象的字节码,即Class对象。

      (2)BeanInfo类中有getPropertyDescriptors()的方法,可获取所有的JavaBean类中的属性信息,返回一个PropertyDescriptor[]。

      (3)在通过遍历的形式,获取与想要的那个属性信息。

      2、以getX为例,步骤实现的代码示例:

     1 private static Object getProperty(Object pt1, String propertyName)
     2             throws IntrospectionException, IllegalAccessException,
     3             InvocationTargetException {        
     4         BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
     5         PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
     6         Object retVal = null;
     7         for(PropertyDescriptor pd : pds){
     8             if(pd.getName().equals(propertyName))
     9             {
    10                 Method methodGetX = pd.getReadMethod();
    11                 retVal = methodGetX.invoke(pt1);
    12                 break;
    13             }
    14         }
    15         return retVal;
    16 }

      (五)BeanUtils工具包

      1、beanutils包下载及添加

      (1)下载地址:http://commons.apache.org/proper/commons-beanutils/

      (2)两种添加方式:

      Ø 方式1:项目上“右键”—— Build Path —— Configure Build Path —— 选择Liberiers标签 —— AddExternal Jars —— 选择要导入的jar包。这种方式属于“本地添加”,存在的问题就是如果jar路径发生变化,项目就不能使用到这个jar包。

      Ø 方式2:在项目中建立一个lib目录,专门用于存放项目所使用到的jar工具包。将要使用到jar包复制进来。在Eclipse的Package Explorer面板中,在jar文件上点右键——选择Builder Path——Add to BiuldPath,添加完成。这样做的好处:jar随项目一起移动。

      2、可能出现的问题

      问题:添加beanutils工具包后,可能会出现org/apache/commons/logging/logFactory找不到

      解决方法:下载commons-logging.jar,同beanutils添加步骤一样,添加日志jar包即可。

      3、BeanUtils工具应用,代码示例

     1 import org.apache.commons.beanutils.BeanUtils;
     2 import org.apache.commons.beanutils.PropertyUtils;
     3 public class IntroSpectorDemo {
     4     public static void main(String[] args) throws Exception {
     5         reflectPoint rp1 = new reflectPoint(3,5);
     6         String propertyName = "x";
     7         //    用BeanUtils工具包的方法
     8         System.out.println(BeanUtils.getProperty(rp1, "x"));//get
     9         BeanUtils.setProperty(rp1, "x", "9");//set
    10         System.out.println(rp1.getX());
    11     }
    12 }

      4、BeanUtils和PropertyUtils的区别?

      BeanUtils工具包中还有一个工具类PropertyUtils,用法跟BeanUtils一样。区别在于:

      (1)BeanUtils会对JavaBean的属性的类型进行转换,如属性本身是integer,会转换为String。

      (2)PropertyUtils以属性本身的类型进行操作。

    1 //用BeanUtils工具包的工具类BeanUtils方法
    2 BeanUtils.setProperty(rp1, "x", "9");//set,9是String
    3 System.out.println(BeanUtils.getProperty(rp1, "x"));//get
    4 System.out.println(BeanUtils.getProperty(rp1, "x").getClass().getName());//java.lang.String
    5 
    6 //BeanUtils工具包中的PropertyUtils的操作
    7 PropertyUtils.setProperty(rp1, "x", 9);//9是Integer
    8 System.out.println(PropertyUtils.getProperty(rp1, "x"));
    9 System.out.println(PropertyUtils.getProperty(rp1,"x").getClass().getName());//java.lang.Integer

    =============================Annotation(注解)==============================

    二、注解(Annotation

      (一)概述

      1、注解(Annotation)相当于一种标记,在程序中加了注解就等于为程序打上了某种标记。

      2、标记可以加在包,类,字段,方法,方法的参数以及局部变量上。

      3、格式:@ 注解名称

      (二)Java提供的几个基本注解

      1、@Deprecated:表示告知调用者,该成员函数、字段等已经过时,不再推荐使用。

      (1)让程序部提示函数弃用(过时)?需要在main方法前面,写上@Suppress Warings(“deprecation”)

      (2)注解一个函数过时?在函数的上一行,写上@deprecated

      2、@Override:表示覆盖父类方法。

      (三)注解的应用结构图

      (四)自定义注解及其应用

      1、格式:@interface name{statement},如public @interface MyAnnotation{}

      2、在类上添加注解:

      @MyAnnotation

      public class AnnotationTest{}

      3、元注解(@Retention、@Target)

      Ø Retetion:用于说明注解保留在哪个阶段(即注解的生命周期)。一个注解的生命周期包括:java源文件→class文件→内存中的字节码[雨林木风1] ,其有三种取值:

      (1)RetetionPolicy.SOURSE:java源文件时期,如@Overried和@SuppressWarning

      (2)RetetionPolicy.CLASS: class文件时期(默认阶段)

      (3)RetetionPolicy.RUNTIME:运行时期,如@Deprecated

      如:在某注解类上加@Retention(RetentionPolicy.RUNTIME),表示此注解会一直存在。

      Ø Target:用于说明注解类的使用范围(如:作用在方法上、类上,默认值是任何地方)

      其值可设置为枚举类ElementType类中的任何一个,包括:包、字段、方法、方法参数、构造器、类等值。取值为:

        ANNOTATION_TYPE:注释类型声明;

        CONSIRUCTOR:构造器声明;

        FIELD:字段声明;

        LOCAL_VARIABLE:局部变量声明;

        METHOD:方法声明;

        PACKAGE:包声明;

        PARAMETER:参数声明;

        TYPE:类、接口(包含注释类型)或枚举声明;

      注意:其中代表类的值是TYPE。因为class、enum、interface和@interface等都是平级的,所以统属于Type。不可用CLASS表示。

      4、注解代码示例

     1 import java.lang.annotation.ElementType;
     2 import java.lang.annotation.Retention;
     3 import java.lang.annotation.RetentionPolicy;
     4 import java.lang.annotation.Target;
     5 @Retention(RetentionPolicy.RUNTIME) 
     6 @Target({ElementType.METHOD,ElementType.TYPE})
     7 //注解类
     8 @interface MyAnnotation {
     9 }
    10 @MyAnnotation
    11 public class AnnotationDemo {
    12     @SuppressWarnings("deprecation")//此注解用于表明不提示过时信息
    13     public static void main(String[] args) {
    14         System.runFinalizersOnExit(true); //此方法已过时
    15         //判断此类是否有MyAnnotation注解
    16         if (AnnotationDemo.class.isAnnotationPresent(MyAnnotation.class)) {
    17             //如果有,则获取该注解
    18             MyAnnotation annotation = AnnotationDemo.class.getAnnotation(MyAnnotation.class);
    19             System.out.println(annotation);
    20         }
    21     }
    22 }

      (五)为注解增加基本属性

      1、注解属性:为注解的参数添加的属性。例如:@MyAnnotation(color="red")

      2、定义基本类型的属性

      (1)在注解类中增加属性:String color();

      (2)定义缺省格式:String value() default “heima;

      3、注解属性应用:

      直接在注解的括号中添加自身的属性:@MyAnnotation(color="red")

      4、value属性:如果注解中有一个名称为value的属性,且只想设置value属性(即其他属性都采用默认值或只有一个value属性),那么可以省略value=部分。例如:

      String value() default "red";

      @MyAnnotation("green")

      5、说明:

      (1)可以为属性值指定缺省值(default),应用时同样可以重新设置属性值。

      (2)用反射方式获得注解对应的实例对象后,可以通过该对象调用属性对应的方法来获取属性值。

      6、代码示例:

     1 import java.lang.annotation.Retention;
     2 import java.lang.annotation.RetentionPolicy;
     3 @Retention(RetentionPolicy.RUNTIME)
     4 public @interface MyAnnotation{
     5 String color() default "blue";
     6 String value();
     7 }
     8 
     9 @MyAnnotation(color="red",value="abc")
    10 public class AnnotationTest {
    11 @SuppressWarnings("deprecation")
    12 @MyAnnotation("xyz")
    13 public static void main(String[] args) throws Exception{
    14     System.runFinalizersOnExit(true);
    15     if(AnnotationTest.class.isAnnotationPresentMyAnnotation.class)){
    16             System.out.println(annotation.color());
    17             System.out.println(annotation.value());
    18         }
    19     }
    20 }

      (六)为注解增加高级属性

      1、数组类型的属性:

      如:int[]arrayArr() default {1,2,3}

      应用:@MyAnnotation(arrayArr={2,3,4})

      注:如果数组属性中只有一个元素,这时候属性值部分可以省略大括。

      2、枚举类型的属性:(定义了一个枚举类TrafficLamp,它是EnumTest的内部类,其值是交通灯的三色)

      定义:EnumTest.TrafficLamplamp();

      应用:@MyAnnotation(lamp=EnumTestTrafficLamp.GREEN)

      3、注解类型的属性:(定义一个注解类:MetaAnnotation,其中定义了一个属性:String value())

      定义:MetaAnnotation annotation() default @MetaAnnotation(”xxx”);

      应用:@MyAnnotation(annotation=@MetaAnnotation(”yyy”))//重新赋值

      4、Class类型的属性:

      定义:Class cls();

      应用:@MyAnnotation(cls=AnnotationDemo.class)

      注:这里的.class必须是已定义的类,或是已有的字节码对象

      5、注解的详细语法可通过查看java语言规范了解即javaLanguage Specification

      6、代码示例:

     1 import java.lang.annotation.ElementType;
     2 import java.lang.annotation.Retention;
     3 import java.lang.annotation.RetentionPolicy;
     4 import java.lang.annotation.Target;
     5 @Retention(RetentionPolicy.RUNTIME)//元注释
     6 @Target({ElementType.METHOD,ElementType.TYPE})//元注解,指定使用范围
     7 //注解类
     8 public @interface MyAnnotation {
     9     String color() default "red" ;
    10     String value();
    11     int[] arr() default {1,2,3};
    12     EnumTest.TrafficLamp lamp() default EnumTest.TrafficLamp.GREEN;
    13     MetaAnnotation annotation() default @MetaAnnotation("heima");
    14     Class clazz() default System.class;
    15 }
    16 
    17 //注解类的应用,给属性赋值或者重新赋值  
    18 @MyAnnotation(lamp=EnumTest.TrafficLamp.YELLOW,value="itheima", clazz=AnnotationDemo.class,annotation=@MetaAnnotation("itheima"))
    19 public class AnnotationDemo {
    20     @SuppressWarnings("deprecation")
    21     @MyAnnotation("Method")//自定义注解应用在方法上
    22     public static void main(String[] args) throws NoSuchMethodException, SecurityException {
    23         System.runFinalizersOnExit(true); //一个过时方法
    24         //判断此类是否有MyAnnotation注解
    25         if (AnnotationDemo.class.isAnnotationPresent(MyAnnotation.class)) {
    26             //如果有,则获取该注解
    27             MyAnnotation annotation =AnnotationDemo.class.getAnnotation (MyAnnotation.class);
    28             System.out.println(annotation);//@cn.itheima.Demo.MyAnnotation()
    29             System.out.println(annotation.color());
    30             System.out.println(annotation.value());
    31             System.out.println(annotation.arr().length);
    32             System.out.println(annotation.lamp());
    33             System.out.println(annotation.annotation().value());
    34             System.out.println(annotation.clazz());
    35         }
    36         //获取方法上的注解
    37         Method mainMethod = AnnotationDemo.class.getMethod("main",String[].class);
    38         MyAnnotation annotationMethod = (MyAnnotation) mainMethod.getAnnotation (MetaAnnotation.class);
    39         SuppressWarnings sw=mainMethod.getAnnotation(SuppressWarnings.class);
    40         System.out.println(sw);
    41         System.out.println(annotationMethod);
    42     }
    43 }

     

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

  • 相关阅读:
    VirtualBox的四种网络连接方式详解
    need to be root
    Unreachable catch block for IOException. This exception is never thrown from the try statement body
    git fetch 拉取而不合并
    IOS开发的哪些异常之异常断点
    duplicate报ORA-01017权限问题
    Woody的Python学习笔记4
    微软100题第51题:和为n连续正数序列
    C语言scanf函数详解
    火星人乘坐核动力飞船回故乡
  • 原文地址:https://www.cnblogs.com/jianxingjianyuan2014/p/4012305.html
Copyright © 2011-2022 走看看