----------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -----------
内省
一、内省
内省对应的英文单词为IntroSpector,英文意思是检查、视察、体检之意,对于程序即对内部进行检查,了解更多的底层细节。
二、JavaBean
1、作用:
如果要在两个模块之间传递多个信息,可以将这些信息封装到一个类中,这种类的实例对象通常称之为值对象(Value Object 简称VO)。这些信息在类中用私有字段来存储,如果读取或设置这些字段的值,则需要通过一些响应的方法来访问。
2、定义
lJavaBean是一种特殊的java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。如果方法名为setId,中文意思即为设置id。至于你把它存到哪个变量上,用管吗?如果方法名为getId,中文意思即为获取id,至于你从哪个变量上取,用管吗?去掉set前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小写的。
setId()的属性名------>id
GetId()的属性名----->id
SetCPU的属性名是什么?------>CPU
setUPS的属性名是什么?------>UPS
总之,一个类被当作javabean使用时,javabean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。
l3、一个符合javabean特点的类可以当作普通类一样进行使用,但把它当作javabean用肯定需要带来一些额外的好处,我们才会去了解和应用javabean
好处如下:
第一,JDK中提供了对javabean进行操作的一些API,这套API就称之为内省。如果要你自己去通过getX方法来访问私有的x,怎么做,有一定难度吧,用内省这套api操作javabean比用普通类的方式更方便。 在JAVA EE开发中,经常要使用到javabean,很多环境就要求按javabean方式进行操作,别人都这没用和要求这么做,那你就没有什么挑选的余地!
第二,JDK中提供了对JavaBean进行操作的API,这套API称为内省,若要自己通过getX的方式来访问私有x,可用内省这套API,操作JavaBean要比使用普通的方式更方便。
4、演示
三、对JavaBean的复杂内省操作
1、在IntroSpector类中有getBeanInfo(Class cls)的方法,通过此方法获取BeanInfo实例。参数是相应对象的字节码,即Class对象。
2、BeanInfo类中有getPropertyDescriptors()的方法,可获取所有的JavaBean类中的属性信息,返回一个PropertyDescriptor[]。
3、在通过遍历的形式,获取与想要的那个属性信息。
演示
四、Beanutils 工具包
2、BeanUtils可以将8种基本数据类型进行自动的转换,因此对于非基本数据类型,就需要注册转换器Converter,这就需要ConverUtils包。
3、好处:
1)提供的set或get方法中,传入的是字符串,返回的还是字符串,因为在浏览器中,用户输入到文本框的都是以字符串的形式发送至服务器上的,所以操作的都是字符串。也就是说这个工具包的内部有自动将整数转换为字符串的操作。
2)支持属性的级联操作,即支持属性链。如可以设置:人的脑袋上的眼睛的眼珠的颜色。这种级联属性的属性连如果自己用反射,那就很困难了,通过这个工具包就可以轻松调用。
4、可以和Map集合进行相互转换:可将属性信息通过键值对的形式作为Map集合存储(通过static java.util.Mapdescribe(java.lang.Object bean)的方法)。也可以将Map集合转换为JavaBean中的属性信息(通过static void populate(java.lang.Objectbean, java.util.Map properties)的方法)。
注:要正常使用BeanUtils工具,还要将Apache公司的logging(日志)的jar包也添加进Build Path。
用eclipse如何加入jar包,先只是引入bean包,等程序运行出错后在引入logging包
两种方式:
1,右键项目--选择Properties---Java Build Path--选择Liberiers标签。AddExternal Jars--选择要导入的jar包。即可。
这样做有个问题就是如果jar路径发生变化。项目就不能使用到这个jar包。
2,在项目中建立一个lib目录,专门用于存放项目所使用到的jar工具包。将要使用到jar包复制粘贴进来,并在jar上点右键--选择Builder Path---Add to BiuldPath,即可。
l在前面内省例子的基础上,用BeanUtils类先get原来设置好的属性,再将其set为一个新值。
Get属性时返回的结果是字符串,set属性时可以接收任意类型的对象,通常使用字符串。
用PropertyUtils类先get原来设置好的属性,再将其set为一个新值。
Get属性时返回的结果为该属性本来的类型,set属性时只接收该属性本来的类型。
6、BeanUtils工具包中还有一个工具类PropertyUtils,用法跟BeanUtils一样。区别:
1)BeanUtils会对JavaBean的属性的类型进行转换,如属性本身是integer,会转换为String。
2)PropertyUtils以属性本身的类型进行操作
JDK.1.5新特性——注解
一、概述
1、 注解(Annotation)相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记。以后,javac编译器、开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去干相应的事。
2、标记可以加在包,类,字段,方法,方法的参数以及局部变量上。
3、在java.lang包中提供了最基本的注解(annotation)。
4、格式:@注解类名。
如果只有一个value名称的属性或其他属性缺省,则可@注解名(”属性值”);
如果有多个或不缺省或者需重新赋值,则@注解名(属性名=”属性值”,…)。
二、常用注解
1、 @SuppressWarning(”deprecation”):表示压制过时警告;或者说不要警告过时提示了
SupressWarning是告知编译器或开发工具等不需要再提示指定的警告了;
“deprecation”是警告的信息,即过时警告。
2、@Deprecated:表示告知调用者,该成员函数、字段等已经过时,不再推荐使用。
源代码标记@Deprecated是在JDK1.5中作为内置的annotation引入的,用于表明类(class)、方法(method)、字段(field)已经不再推荐使用,并且在以后的JDK版本中可能将其删除,编译器在默认情况下检测到有此标记的时候会提示警告信息。
例如:假定之前的某个类升级了,其中的某个方法已经过时了,不能够将过时的方法删除,因为可能会影响到之前调用此这个方法的某些程序,这时就可以通过在方法上加这个注解来标记。
3、@Override:表示下面的方法是在覆盖(父类方法),如果不存在覆盖,就会报错。
加上此注解,可对类中的方法判断是否是要覆盖的父类的方法。典型的例子即在类中覆盖equals(Object obj)方法时,其中的参数类型必须是Object,才能被覆盖;若不是,则不存在覆盖。此时如果加上了此注解就会提示警告。
三、自定义注解及其应用
1、定义格式:@interface名称{statement}
如:
最简单的注解类:public @interface MyAnnotation{}
2、元注解(注解的注解)
即在定义注解类的时候加注解。如两个常用于元注解的注解:Retention和Target
1)Retetion:用于说明注解保留在哪个阶段(即注解的生命周期)。
一个注解的生命周期包含:java源程序--(javac)-->class文件--(类加载器)-->内存中的字节码
分别对应Retetion这个枚举类的值:
RetetionPolicy.SOURSE:java源文件时期,如@Overried和@SuppressWarning
RetetionPolicy.CLASS:class文件时期(默认阶段)
RetetionPolicy.RUNTIME:运行时期,如@Deprecated
如:在某注解类上加@Retention(RetentionPolicy.RUNTIME),表示此注解会一直存在。
注:
(1)当在源程序上加了注解,javac将java源程序编译为class文件时,会对注解的生命周期进行判断。如果该注解只保留在源程序,则编译时会将该注解进行相应的处理操作,如去掉。其他类推。
(2)class文件中不是字节码,只有把class文件中的内容加载进内存,用类加载器加载处理后(进行完整的检查等处理),最终得到的二进制内容才是字节码。
2)Target:用于说明注解类的使用范围。如在方法上还是类上,默认值是任何地方。
其值可设置为枚举类ElementType类中的任何一个,包括:包、字段、方法、方法参数、构造器、类等值。取值为:
PACKAGE(包声明)
FIELD(字段声明)
ANNOTATION_TYPE(注释类型声明)
CONSIRUCTOR(构造器声明)
METHOD(方法声明)
PARAMETER(参数声明)
TYPE(类、接口(包含注释类型)或枚举声明)
LOCAL_VARIABLE(局部变量声明)
注意:其中代表类的值是TYPE。因为class、enum、interface和@interface等都是平级的,所以统属于Type。不可用CLASS表示。
3、注解的应用
通过反射方式来获取自定义的注解类,步骤跟注解的应用结构一致,
如:
第一、定义注解类:@interfaceA{}
第二、应用了“注释类”的类:@A class B{}
第三、对“应用注释类的类”进行反射操作的类:class c{...}
操作如下:
B.class.isAnnotionPresent(A.class);//判断是否存在此注解类
A a = B.class.getAnnotation(a.class);//存在的话则得到这个注释类的对象
示例:
4、为注解添加基本属性
(1)属性:一个注解相当于一个胸牌,但仅通过胸牌还不足以区别带胸牌的两个人,这时就需要给胸牌增加一个属性来区分,如颜色等。
(2)定义格式:同接口中的方法一样:String color();
定义缺省格式:String value() default“java”;
(3)应用:直接在注解的括号中添加自身的属性,如:
@MyAnnotation(color=”blue”)
1)如果注解中有一个名称为value的属性,且你只想设置value属性(即其他属性都采用默认值或者你只有一个value属性),那么可以省略value=部分,例如:@SuppressWarnings("deprecation")。
2)可以为属性值指定缺省值(default),应用时同样可以重新设置属性值。
3)用反射方式获得注解对应的实例对象后,可以通过该对象调用属性对应的方法来获取属性值。
5、为注解增加高级属性
(1)可以为注解增加的高级属性的返回值类型有:
1)八种基本数据类型
2)String类型
3)Class类型
4)枚举类型
5)注解类型
6)前五种类型的数组
(2)数组类型的属性:
如:int[]arrayArr() default {1,2,3};//可不定义默认值
应用:@MyAnnotation(arrayArr={2,3,4}) //可重新赋值
注:若数组属性中只有一个元素(或重新赋值为一个元素),这时属性值部分可省略大括号。
(3)枚举类型的属性:
假设定义了一个枚举类TrafficLamp,它是EnumTest的内部类,其值是交通灯的三色。
定义:EnumTest.TrafficLamplamp();
应用:@MyAnnotation(lamp=EnumTestTrafficLamp.GREEN)
(4)注解类型的属性:
假定有个注解类:MetaAnnotation,其中定义了一个属性:String value()
定义:MetaAnnotation annotation() default @MetaAnnotation(”xxx”);
应用:@MyAnnotation(annotation=@MetaAnnotation(”yyy”))//重新赋值
可以认为上面这个@MyAnnotation是MyAnnotaion类的一个实例对象,同样的道理,可以认为上面这个@MetaAnnotation是MetaAnnotation类的一个实例对象,调用代码如下:
MetaAnnotationma =MyAnnotation.annotation();
System.out.println(ma.value());
(5)Class类型的属性:
定义:Class cls();
应用:@MyAnnotation(cls=AnnotationDemo.class)
注:这里的.class必须是已定义的类,或是已有的字节码对象
(6)注解的详细语法可通过查看java语言规范了解即javaLanguage Specification
示例: