1 什么是javaBean
JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要是用于访问私有字段,且方法名符合某种命名规则.
2 javaBean有什么作用
如果要在两个模块之间传递多个信息,可以讲这些信息封装到一个javaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object 建成VO)。这些信息在类中用私有字段来存数,想要获取这些信息可以通过一定的方法来获取。
3 如何获取JavaBean中的信息
JavaBean中的属性是根据其中的getter和setter方法确定的,并不是根据其中的成员变量,如果方法名为setId,中文意思即为设置 ID,至于把它存在哪个变量上,无所谓都是表示设置ID 同样如果方法名字为getID 中文意思即为获取ID至于从哪个变量上去,无所谓都是表示取ID,一般按照如下规则命名 去掉set前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小的
如setId()àid; isLast()àlast; setCPU—>CPU; getupsàUPS;
总之一个类被当做javabean使用时,javaBean的属性石根据方法名推断出来的,它根本看不到Java类内部的成员变量
4 JavaBean的好处
在JavaEE开发中,经常要使用JavaBean,很多环境就要求按JavaBean方式进行操作,主流。
JDK中提供了对JavaBean进行操作的一些API,这些API就称为内省,如果要你自己去通过getX 方法来访问私有的X是由一定难度的,用内省这套API操作JavaBean比普通类的方式要方便。
5示例对JavaBean的操作
- package cn.itheima.fanshe;
- import java.beans.PropertyDescriptor;
- import java.lang.reflect.Method;
- public class beantest {
- public static void main(String[] args) throws Exception{
- //通过bean方式获取对象 rd1的name值
- RoleDemo rd1 = new RoleDemo("张三","type1");
- //定义一个要获取的属性名 这个是name
- String propertyName = "name";
- //获取属性 参数 指定要获取的属性,和指定的类
- PropertyDescriptor pd = new PropertyDescriptor(propertyName,rd1.getClass());
- //得到属性了 进一步就可以得到属性的get set方法 如下即可得到了X属性的读方法
- Method methodgname = pd.getReadMethod();
- //有了这个属性的读方法我们就可以用这个方法在rd1方法上调用。
- Object retval = methodgname.invoke(rd1);
- System.out.println(retval);
- //输出 调用了带两个属性的构造器 张三
- Method methodsname = pd.getWriteMethod();
- //有了这个属性的读方法我们就可以用这个方法在rd1方法上调用。
- Object retval1 = methodsname.invoke(rd1,"李四");
- System.out.println(rd1.getName());
- //输出 李四
- }
- }
可以到上面获取属性值的时候有代码复用,那么可以抽取出来构成一个方法,用的时候调用即可
- package cn.itheima.fanshe;
- import java.beans.IntrospectionException;
- import java.beans.PropertyDescriptor;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- public class beantest {
- public static void main(String[] args) throws Exception{
- //通过bean方式获取对象 rd1的name值
- RoleDemo rd1 = new RoleDemo("张三","type1");
- //定义一个要获取的属性名 这个是name
- String propertyName = "name";
- Object retval = getProperty(rd1, propertyName);
- System.out.println(retval);
- Object newVal = "李四";
- //输出 调用了带两个属性的构造器 张三
- getProperts(rd1, propertyName, newVal);
- System.out.println(rd1.getName());
- //输出 李四
- }
- private static void getProperts(Object rd1, String propertyName,
- Object newVal) throws IntrospectionException,
- IllegalAccessException, InvocationTargetException {
- PropertyDescriptor pd = new PropertyDescriptor(propertyName,rd1.getClass());
- Method methodsname = pd.getWriteMethod();
- Object retval1 = methodsname.invoke(rd1,newVal);
- }
- //重构的方法
- private static Object getProperty(Object rd1, String propertyName)
- throws IntrospectionException, IllegalAccessException,
- InvocationTargetException {
- PropertyDescriptor pd = new PropertyDescriptor(propertyName,rd1.getClass());
- Method methodgname = pd.getReadMethod();
- Object retval = methodgname.invoke(rd1);
- return retval;
- }
- }
对JavaBean的复杂内省操作:在IntroSpector类中有getBeanInfo(Class cls)的方法。
获取Class对象的Bean信息,返回的是BeanInfo类型。
BeanInfo类中有getPropertyDescriptors()的方法,可获取所有的BeanInfo的属性信息,返回一个PropertyDescriptor[]。
在通过遍历的形式,找出与自己想要的那个属性信息。
如:改写get方法:
- ...
- BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
- PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
- Object value = null;
- for(PropertyDescriptor pd : pds){
- if(pd.getName().equals(propertyName)){
- Method methodGetX = pd.getReadMethod();
- value = methodGetX.invoke(pt1);
- break;
- }
- }
- …
6 Beanutils工具包
为了便于操作JavaBean,前辈们就编写了BeanUtils包,里面封装了很多对JavaBean的操作,我们在用的时候可以直接拿过来用。
好处是什么呢有如下三个好处
一提供的set或get方法中,传入的是字符串,返回的还是字符串,因为在浏览器中,用户输入到文本框的都是以字符串形式发送至服务器上的,所以操作的都是字符串。也就是说,这个工具包的内部有自动将证书转换为字符串的操作
一是支持属性的级联操作,即支持属性链,如果可以设置,人的脑袋上的眼睛的眼珠的颜色。这种级联属性的属性链如果用自己反射,那就很困难了通过这个工具包就可以轻松调用。
一是 可以和Map集合进行相互转换,可以讲属性信息通过键值对的形式作为Map集合存储(通过 staticJava.util.Mapdecribe(java.lang.Objectbean)的方法)也可以讲Map集合转换为JavaBean 中的属性信息,(通过static void populate(java.lang.object bean,java.util.map properties)的方法)。
上面我们介绍了通过bean方式获取对象 rd1的name值的方法,下面我们可以利用BeanUtils包简化操作
- //通过bean方式获取对象 rd1的name值
- RoleDemo rd1 = new RoleDemo("张三","type1");
- //定义一个要获取的属性名 这个是name
- String propertyName = "name";
- System.out.println(BeanUtils.getProperty(rd1, propertyName));
- BeanUtils.setProperty(rd1, propertyName, "李四");
- System.out.println(rd1.getName());
- 输出张三 李四 显然简化了操作
注解
java提供的几个基本注解
1、 @suppressWarning(“deprecation”)à压制警告
suppressWaring是告知编译器或开发工具等提示指定的编译器警告
deprecation 是告知具体的信息即方法已过时
2、 @Deprecatedà提示成员已经过时,不再推荐使用。
源代码标记@Deprecated是在JDK1.5中作为内置的annotatin引入的,用于表明类、方法、字段已经不再推荐使用,并且在以后的JDK 版本中,可能将其删除,在编译器在默认情况下检测到此标记时,会提示警告信息:假如之前的某个类升级了,其中的某个方法已经过时了,不能够将过时的方法删 除,因为可能会影响到调用此类的这个方法的某些程序,这是就可以通过在方法上加这个注解。
3、@Overrideà提示覆盖(父类方法)
加上此注解,可对自己类中的方法判断是否是要覆盖的父类的方法,典型的例子即在集合中覆盖equals(Object obj)方法,其中的参数类型必须是Object,才能被覆盖,若不是,加上此注解就会提示警告。
总结
注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记,以后javac编译器,开发工具盒其他程序可以用反射来了 解你的类及各种元素上有无何种标记,看你有什么标记就去干相应的事,标记可以加在包,类,字段,方法,方法的参数上以及局部变量上
4、 自定义注解
自定义注解和接口差不都 ,只是在interface前面加一个@
public @interface Myannotation {} 这个代码是一个最简单的注解,这个注解没有属性,也可以理解为是一个标记注解。就像Serlializable接口一样是一个标记接口,里面未定义方法。 也可以再里面加上方法public @interface MyAnnotation{String value() }
使用子低昂一注解
@MyAnnotation(“abc”)
publicvoid myMethod(){}
这里的abc传给了Value 有个规定就是如果没有属性名称的值,而这个注解有有Value属性,就将这个值赋给Value属性,如果没有,就出现编译错误。
在使用的时候出了可以省略属性值,还可以使用默认值
- public @interface MyAnnotation
- {
- public String MyMethod() default “abc”;
- }
- //使用默认值
- @MyAnnotation
- public void MyMethod(){}
5、 对注解进行注解
为注解提供的注解叫做 元注解 这种注解主要是 Target Retention Documented 和 Inherited
1) Target
target表示目标,这个注解在用的时候是与某一些目标相关的。看如下示例
- @Target({ElementType.METHOD})
- @interface MyAnnotation{}
- @MyAnnotation //放在类上面是错误的
- public class Class1
- {
- @MyAnnotation
- public void myMethod1(){}
- }
上面这段代码定义了一个注解MyAnnotation和一个类Class1,使用MyAnnotation分别对Class1和myMethod1进行注解,编译这段代码是无法通过的,因为@Target({ElementType.METHOD})
指定了使用注解的目标是一个方法而不是其他任何语句元素。。由此看见,target所指定的目标就是java中的语句元素,比如类,接口,方法等。 比如只可以对方法和构造函数进行注解可以写成
@Target({ElementType.METHOD,ElementType.CONSTRUCTOR})
@interfaceMyAnnotation{}
2) Retention
注解只有在被保存到class文件中才可以被读出来,Retention就是为设置注解是否保存在class文件中而存在的。详细用法如下
//不将注解保存在class文件中,类似 // 一样在编译时被过滤掉
@Retention(RetentionPolicy.SOURCE)
@interface MyAnnotation1{}
//只将注解保存在class文件中,在运用反射读取注解时忽略掉这些注解。
@Retention(RetentionPolicy.CLASS)
@interface MyAnnotation2{}
//将注解保存在class文件中,通过反射也可以读出注解
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation3{}
3) Documented
这个注解跟文档有关,在默认的情况下使用javadoc自动生成文档时,直接将被忽略掉,如果想在文档中包含注解那必须使用Documented为文档注释,例如
- @interface MyAnnotation{ }
- @MyAnnotation
- class Class1
- {
- public void myMethod() { }
- }
在使用的javadoc为这段代码生成文档时并不将@MyAnnotation包含进去。生成的文档对Class1的描述为 class Class1 extends java.lang.Object
如果这样定义MyAnnotation将会出现另一个结果。
@Documented
@interface MyAnnotation{}
生成文档为
@MyAnnotation
class Class1 extendsjava.lang.Object
4) Inherited
这个是关于继承方面的元注解,不向protected和public成员都将被子类继承一样,在默认的情况下,父类的注解并不会被子类继承,如果要继承,就必须加上Inherited
- @Inherited
- @interface MyAnnotation { }
- @MyAnnotation
- public class ParentClass {}
- public class ChildClass extends ParentClass { }
- 在以上代码中ChildClass和ParentClass一样都已被MyAnnotation注解了。
6、 通过反射查看注解
在JDK1.5以后可以通过反射来获取注解了。之前的版本是不可以的。
想要得到某一个类或接口的租借信息,可以使用下面代码
Annotationannotation = AnnotationTest.calss.getAnnotation(MyAnnotation.class);
想要得到全部的注解信息可以用如下方式
//包括继承的所有注解
Annotation[]annotations =AnnotationTest.class.getAnnotations();
//不包括继承的所有注解
Annotation[] anntations = AnnotationTest.class.getDeclaredAnnotations()