黑马程序员—JAVA高新技术_JDK1.5新特性II

来源:互联网 发布:js获取pdf文件大小 编辑:程序博客网 时间:2024/06/01 17:25

JavaBean与内省

JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。
 如果要在两个模块之间传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问,JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。去掉set或get前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的。
setId()的属性名:id
setCPU的属性名是什么:CPU
 总之,一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。

对JavaBean的简单内省操作
通过内省的方式对ReflectPoint对象中的成员变量进行读写操作。
示例:

public class ReflectPoint {       private int x ;       private int y ;             public ReflectPoint(int x, int y) {             super();             this.x = x;             this.y = y;      }      public int getX() {             return x ;      }       public void setX(int x) {             this.x = x;      }       public int getY() {             return y ;      }       public void setY(int y) {             this.y = y;      }}
<pre class="java" name="code">public class ReflectTest {       public static void main(String[] args) throws Exception {         ReflectPoint pt1 = new ReflectPoint(3, 5);                 String propertyName = "x";         PropertyDescriptor pd1 = new PropertyDescriptor(propertyName, pt1.getClass());         Method readMethod = pd1.getReadMethod();         Object retVal = readMethod.invoke(pt1);         System. out.println(retVal);         //结果:3                 PropertyDescriptor pd2 = new PropertyDescriptor(propertyName, pt1.getClass());         Method writeMethod = pd2.getWriteMethod();         Object value = 7;         writeMethod.invoke(pt1,value);         System. out.println(pt1.getX());         //结果:7       }}

Beanutils工具包

Beanutils工具包是由Apache公司所开发,主要是方便程序员对Bean类能够进行简便的操作。

在前面内省例子的基础上,用BeanUtils类先get原来设置好的属性,再将其set为一个新值。get属性时返回的结果为字符串,set属性时可以接受任意类型的对象,通常使用字符串。

String str = BeanUtils.getProperty(pt1, "x");BeanUtils.setProperty(pt1, "x", "9");

用PropertyUtils类先get原来设置好的属性,再将其set为一个新值。get属性时返回的结果为该属性本来的类型,set属性时只接受该属性本来的类型。

PropertyUtils.setProperty(pt1, "x", 9);int i = PropertyUtils.getProperty(pt1, "x");

注解

注解是java 的一个新的类型(与接口很相似),它与类、接口、枚举是在同一个层次,它们都称作为java 的一个类型(TYPE)。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。它的作用非常的多,例如:进行编译检查、生成说明文档、代码分析等。

JDK提供的几个基本注解:a. @SuppressWarnings:该注解的作用是阻止编译器发出某些警告信息。它可以有以下参数:deprecation:过时的类或方法警告。unchecked:执行了未检查的转换时警告。fallthrough:当Switch 程序块直接通往下一种情况而没有Break 时的警告。path:在类路径、源文件路径等中有不存在的路径时的警告。serial:当在可序列化的类上缺少serialVersionUID 定义时的警告。finally:任何finally 子句不能完成时的警告。all:关于以上所有情况的警告。b. @Deprecated:该注解的作用是标记某个过时的类或方法。c. @Override:该注解用在方法前面,用来标识该方法是重写父类的某个方法。元注解:a. @Retention:它是被定义在一个注解类的前面,用来说明该注解的生命周期。它有以下参数:RetentionPolicy.SOURCE:指定注解只保留在一个源文件当中。RetentionPolicy.CLASS:指定注解只保留在一个class 文件中。RetentionPolicy.RUNTIME:指定注解可以保留在程序运行期间。b. @Target:它是被定义在一个注解类的前面,用来说明该注解可以被声明在哪些元素前。它有以下参数:ElementType.TYPE:说明该注解只能被声明在一个类前。ElementType.FIELD:说明该注解只能被声明在一个类的字段前。ElementType.METHOD:说明该注解只能被声明在一个类的方法前。ElementType.PARAMETER:说明该注解只能被声明在一个方法参数前。ElementType.CONSTRUCTOR:说明该注解只能声明在一个类的构造方法前。ElementType.LOCAL_VARIABLE:说明该注解只能声明在一个局部变量前。ElementType.ANNOTATION_TYPE:说明该注解只能声明在一个注解类型前。ElementType.PACKAGE:说明该注解只能声明在一个包名前。

注解的生命周期一个注解可以有三个生命周期,它默认的生命周期是保留在一个CLASS 文件,但它也可以由一个@Retetion 的元注解指定它的生命周期。a. java 源文件当在一个注解类前定义了一个@Retetion(RetentionPolicy.SOURCE)的注解,那么说明该注解只保留在一个源文件当中,当编译器将源文件编译成class 文件时,它不会将源文件中定义的注解保留在class 文件中。b. class 文件中当在一个注解类前定义了一个@Retetion(RetentionPolicy.CLASS)的注解,那么说明该注解只保留在一个class 文件当中,当加载class 文件到内存时,虚拟机会将注解去掉,从而在程序中不能访问。c. 程序运行期间当在一个注解类前定义了一个@Retetion(RetentionPolicy.RUNTIME)的注解,那么说明该注解在程序运行期间都会存在内存当中。此时,我们可以通过反射来获得定义在某个类上的所有注解。

注解的定义一个简单的注解:public @interface Annotation01 {//定义公共的final静态属性.....//定以公共的抽象方法......} a. 注解可以有的成员:注解和接口相似,它只能定义final 静态属性和公共抽象方法。b. 注解的方法1.方法前默认会加上public abstract2.在声明方法时可以定义方法的默认返回值String color() default "blue";String[] color() default {"blue", "red",......}3.方法的返回值类型可以有:8 种基本类型,String、Class、枚举、注解及这些类型的数组。

示例代码:定义一个注解

@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");}

注解的使用
注解的使用分为三个过程:定义注解-->声明注解-->得到注解
a. 定义注解(参照上面的注解定义)
b. 声明注解
1. 在哪些元素上声明注解
如果定义注解时没有指定@Target 元注解来限制它的使用范围,那么该注解可以使用在ElementType 枚举指定的任何一个元素前。否则,只能声明在@Target 元注解指定的元素前。
一般形式:@注解名()
2. 对注解的方法的返回值进行赋值
对于注解中定义的每一个没有默认返回值的方法,在声明注解时必须对它的每一个方法的返回值进行赋值。
一般形式:
@注解名(方法名=方法返回值,、、、、、、)
如果方法返回的是一个数组时,那么将方法返回值写在{}符号里
@注解名(方法名={返回值1,返回值2,、、、、、、},、、、、、、、)
3. 对于只含有value 方法的注解,在声明注解时可以只写返回值。
c. 得到注解
对于生命周期为运行期间的注解,都可以通过反射获得该元素上的注解实例。
1、声明在一个类中的注解
可以通过该类Class 对象的getAnnotation 或getAnnotations 方法获得。
2、声明在一个字段中的注解
通过Field 对象的getAnnotation 或getAnnotations 方法获得
3、声明在一个方法中的注解
通过Method 对象的getAnnotation 或getAnnotations 方法获得

示例代码:使用注解

@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());}}

总结
注解可以看成是一个接口,注解实例就是一个实现了该接口的动态代理类。
注解大多是用做对某个类、方法、字段进行说明,标识的。以便在程序运行期间我们通过反射获得该字段或方法的注解的实例,来决定该做些什么处理或不该进

 

0 0