黑马程序员——【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([email protected](”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,[email protected]("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培训、期待与您交流! ----------

时间: 2024-10-27 13:14:20

黑马程序员——【Java高新技术】——JavaBean、注解的相关文章

黑马程序员——Java高新技术代理

代理 普通代理 很多时候,我们使用别人代码往往会发现别人代码的功能并不是十分符合我们的需求,调用别人的方法的时候,总是先new一个对象,然后我们的前处理做完,然后调用别人代码的方法,再加入后处理,这样做往往十分麻烦.代理就为其他类提供了一种控制其对象的方法.代理类和委托类必须实现同一个接口,这样代理类才能在需要的时候代替委托类对象,执行委托类的方法. interface Solution{ public void doSomething(); } //委托类Demo实现了接口 class Dem

黑马程序员——java高新技术(新特性、反射、泛型)

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- java高新技术 第一部分——JDK1.5新特性 1.增强for循环 格式: for(元素类型 变量名 : Collection集合 & 数组 ) { }//增强for循环括号里写两个参数,第一个是声明一个变量,第二个就是需要迭代的容器 高级for循环和传统for循环的区别: 高级for循环在使用时,必须要明确被遍历的目标.这个目标,可以是Collection集合或者数组,如果遍历Collec

黑马程序员——Java高新技术——反射机制

点击打开链接 点击打开链接 点击打开链接 android培训.<a">点击打开链接 点击打开链接 java培训.期待与您交流!">点击打开链接 点击打开链接 反射的基石--Class类 Java程序中的各个java类属于同一类事物,描述这类事物的java类名就是Class. Class类没有构造函数,不能new对象.怎么得到Class类的实例,有3中方法: ①类名.Class    Class  c1=Date.class; ②对象.getClass 获取对象所属的字

黑马程序员——Java高新技术——反射的复写

由于第一段视频学习效果不理想,希望重新看一遍反射视频,并多方面寻找资料,重新写一遍总结,以期java能力早日提高. Java——反射 一.Class类 Class 类的实例表示正在运行的 Java 应用程序中的类和接口.所以,Class可以提供方法获得动态的java类中的各个属性: (由定义可以知道Class创建的思路就是获得某一个特定java类的信息然后传给Class的对象,那么具体怎么做呢?) 这里说得java类的信息指的就是该java类的计算机的字节码:传给 Class cls1: 所以有

黑马程序员----Java高新技术之反射学习总结

------- android培训.java培训.期待与您交流! ---------- 反射的概念. 1.Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类中的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. 精妙的总结就是:反射就是将Java类中的各个成分映射成相应的Java类. 3.在Java中,描述事物的各种类同样也是一种事物,也可以用面向对象的方法来描述,即也有一个类来描述众多的J

黑马程序员——java高新技术——网络编程

点击打开链接 点击打开链接 点击打开链接 android培训.<a">点击打开链接 点击打开链接 java培训.期待与您交流!">点击打开链接 点击打开链接 网络编程 网络模型 l   OSI参考模型 l   TCP/IP参考模型 网络通讯要素 l   IP地址:网络中设备的标识,不易记忆,可用主机名,本地回环地址,127.0.0.1  主机名:localhost l   端口号:用于标识进程的逻辑地址,不同进程的标识,有效端口:0~65535,其中0~1024系统使

黑马程序员——JAVA高新技术——反射

----------android培训.java培训.java学习型技术博客.期待与您交流!------------ 一.对于反射的概念 对于JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制. JAVA反射(放射)机制:"程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言".从这个观点看,Perl,Python,Ruby

黑马程序员——java高新技术——IO其他流对象

点击打开链接 点击打开链接 点击打开链接 android培训.<a">点击打开链接 点击打开链接 java培训.期待与您交流!">点击打开链接 点击打开链接 IO其他对象 PrintStream:字节打印流.为其他输出流添加了功能,提供了打印方法,可以将各种数据类型的数据原样打印. 构造函数可以接受的参数类型:file对象,字符串路径,字节输出流. 方法:println():打印各种基本数据类型. PrintWrite:字符打印流.构造函数可以接受的参数类型:file

黑马程序员_Java高新技术

1  JDK5的新特性 1.1 静态导入       在API中那些不需要new对象的类,可以在类文件的开头,import static java.lang.Math.*;这里把Math中的所有的静态方法都导入了,在类中不需要调用Math类就能直接用Math的方法了 package cn.wjd.staticimport; import static java.lang.Math.*; public class StaticImport { public static void main(Str

黑马程序员_高新技术_1_Java反射

------- android培训.java培训.期待与您交流! ---------- 0.反射知识体系 下图为反射整体的知识体系,把握住此图也就全局上掌握住反射所有内容. 1.反射概论 1)反射概念 其实字面上可以这么理解反射,平时使用类时都是由类new出对象,而反射则是通过对象"反射"出类的信息,好比一个人照镜子可以看到人类的特征,而看出机制就是镜子反射. 2)Java对象两种类型 Java程序中的许多对象在运行时会出现两种类型:编译时类型和运行时类型.如下代码: Person p