基础加强第六天

3.11
反射的作用-实现框架功能
框架与框架要解决的核心问题:框架与工具类有区别,工具类被用户的类调用,而框架则是调用用户提供的类。
框架要解决的核心问题:因为在写程序是无法知道要被调用的类名,所以,在程序中无法直接new某个类的实例对象了,而要用反射方式来做。
例:
配置文件config.properties
className=java.util.HashSet
实现类
 public static void main(String[] args) throws Exception{
  InputStream ips=new FileInputStream("config.properties");
  Properties pro=new Properties();
  pro.load(ips);
  ips.close();
  String className=pro.getProperty("className");
  Collection collections=(Collection)Class.forName(className).newInstance();
  
 }
在配置文件中只要修改className的值,实现类就会产生不同的结果。
实现了一个小框架的作用。
找配置文件我学习了几种方法可以用InputStream ips=new FileInputStream("config.properties");注意,在目录的最前面不能加“/”,否则会出错。
如果配置文件放在包里面,和类放在一起,可以用
InputStream ips=类名.class.getClassLoader().getResourceAsStream("cn/itcast/day1/config.properties");
相对路径:InputStream ips=类名.class.getResourceAsStream("config.properties");
绝对路径:InputStream ips=类名.class.getResourceAsStream("/cn/itcast/day1/config.properties");
但是最好将配置文件放在classpass目录下。配置文件往往都是用类加载器加载


内省(IntroSpector)——主要对javaBean进行操作
javabean是一种特殊的java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。
如果要在两个模块之间传递多个信息,可以将这些信息封装到一个javabean中,这种javabean的实例对象通常称为值对象(Value Object,简称VO)。这些信息在类中用私有字段

来存储,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问,javaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。如果方法

名为setId或getId,去掉set或get前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改写成小的。
例:
class Person{
 private int x;
 public int getAge(){
  return x;
 }
 public void setAge(int age){
  this.x=age;
 }
}
此类中的属性名为age

例:gettime的属性名为time
    setTime的属性名为time
    getCPU的属性名为CPU,如果第二个字母是大写,则第一个字母大小写不变。
总之,一个类被当作javabean来使用时,javabean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。
一个符合javabean特点的类可以当作普通类一样进行使用,但把它当javabean用带来的好处有:
1、在javaEE开发中,经常要使用到javabean。很多环境就要求按javabean方式进行操作。
2、JDK中提供了对javabean进行操作的一些API,这套API就称为内省。
示例代码:
public class javaBeanPoint {
 
 private int x;
 private int 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;
 }
 
 public javaBeanPoint(int x, int y) {
  super();
  this.x = x;
  this.y = y;
 }

}
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class IntroSpectorTest {

 /**
  * @param args
  */
 public static void main(String[] args) throws Exception{
  javaBeanPoint jbp=new javaBeanPoint(3,5);
  String propertyName="x";
  
  Object retVal = getProperty(jbp, propertyName);
  System.out.println(retVal);
  
  Object value=10;
  setProperty(jbp, propertyName, value);
  System.out.println(jbp.getX());


 }

 private static void setProperty(javaBeanPoint jbp, String propertyName,
   Object value) throws IntrospectionException,
   IllegalAccessException, InvocationTargetException {
  PropertyDescriptor pd1=new PropertyDescriptor(propertyName, jbp.getClass());
  Method methodSetX=pd1.getWriteMethod();
  methodSetX.invoke(jbp,value);
 }

 private static Object getProperty(Object jbp, String propertyName)
   throws IntrospectionException, IllegalAccessException,
   InvocationTargetException {
  /*PropertyDescriptor pd=new PropertyDescriptor(propertyName, jbp.getClass());
  Method methodGetX=pd.getReadMethod();
  Object retVal=methodGetX.invoke(jbp);*/
  
  BeanInfo beanInfo=Introspector.getBeanInfo(jbp.getClass());
  PropertyDescriptor[] pds=beanInfo.getPropertyDescriptors();
  Object retVal=null;
  for(PropertyDescriptor pd:pds){
   if(pd.getName().equals(propertyName)){
    Method methodGetX=pd.getReadMethod();
    retVal=methodGetX.invoke(jbp);
    break;
   }
  }
  
  return retVal;
 }

}

演示了用eclipse自动生成javaBeanPoint类的setter和getter方法并演示了如何读取和设置属性值。再new一个PropertyDescription对象,用一段代码读取javabean的属性,然后

再用一段代码设置javabean的属性
只要调用这个方法,并给这个方法传递了一个对象,属性名和设置值,就可以完成属性修改的功能。
得到BeanInfo最好采用“obj.getClass()”方式,而不要采用“类名.class”方式,这样程序更加通用。
采用遍历BeanInfo的所有属性方式来查找和设置某个javaBeanPoint对象的x属性。在程序中把一个类当作javabean来看,就是调用IntroSpector.getBeanInfo方法,得到的

BeanInfo对象封装了把这个类当作javabean看的结果信息。


Beanutils工具包
在eclipse中加入jar包,先引入beanutils包,等程序运行出错后再引入logging包,
用BeanUtils类先get原来设置好的属性,再将其set为一个新值,get属性时返回的结果为字符串,set属性时可以接受任意类型的对象,通常使用字符串。
用PropertyUtils类先get原来设置好的属性,再将其set为一个新值,get属性时返回的结果为该属性本来的类型,set属性时只接受该属性本来的类型。
例:
public static void main(String[] args) throws Exception{
 ReflectPoint rp=new ReflectPoint(3,5);
 System.out.println(BeanUtils.getProperty(rp,"x"));
 System.out.println(BeanUtils.getProperty(rp,"x").getClass().getName);
 BeanUtils.setProperty(rp,"x","22");
 System.out.println(rp.getX());

 /*
 Map map={name:"zxx",age:22};
 BeanUtils.setProperty(map,"name","wangli");
 */
 BeanUtils.setProperty(rp,"birthday.time","1989");
 System.out.println(BeanUtils.getProperty(rp,"birthday.time"));

 PropertyUtils.setProperty(rp,"x",12);
 System.out.println(PropertyUtils.getProperty(rp,"x"));
 System.out.println(PropertyUtils.getProperty(rp,"x").getClass().getName);
}

import java.util.Date;
public class ReflectPoint{
 private Date birthday=new Date();
 private int x;
 public int y;
 public ReflectPoint(int x,int y){
  super();
  this.x=x;
  this.y=y;
 }
 public Date getBirthday(){
  return birthday;
 }
 public void setBirthday(Date birthday){
  this.birthday=birthday;
 }
 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;
 }
}
打印结果为:
5
java.lang.String
22
1989
12
java.lang.Integer

BeanUtils和PropertyUtils的区别:
BeanUtils是以字符串的形式对java进行操作
PropertyUtils是以属性本身的类型对java进行操作

注解
注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记,在javac编译器,开发工具和其他程序可以用反射来观察你的类及各种元素上

有无何种标记,有什么标记,就会执行相应标记的动作。标记可以加在包,类,字段,方法,方法的参数以及局部变量上。

java提供的几个基本注解
@SuppressWarnings("deprecation")
用在已知道此方法过时,让编译器或开发工具不给予提示
@Deprecated
如果在方法上加此注解,在其他地方调用的时候就会提示此方法已过时
@Override
是否覆盖了父类的方法

自定义一个简单的注解:public @interface itcastAnnotation{}
把此注解加在某个类上:
@itcastAnnotation
public class AnnotationTest{}
用反射进行测试AnnotationTest的定义上是否有@itcastAnnotation
@Retention元注解的三种取值:
RetetionPolicy.SOURCE       java源文件、
RetetionPolicy.ClASS        class文件、
RetetionPolicy.RUNTIME      内存中的字节码

@Override注解的属性值为SOURCE
@SuppressWarnings注解的属性值为SOURCE
@Deprecated注解的属性值为RUNTIME
@Target元注解:Target的默认值为任何元素,设置Target等于ElementType.METHOD,就必须将注解加在method上,设置Target等于ElementType.TYPE,可以将注解加在类,接口,

枚举等等上

注解的属性
一个注解相当于一个胸牌,如果有胸牌,说明就是某个学校的学生,但还不知道是哪个班的学生,如果在胸牌上增加一个班级的属性就可以明显的知道你是哪个班的同学。
定义基本类型的属性和应用属性
在注解类中增加String color();
@itcastAnnotation(color="red")
用反射方式获得注解对应的实例对象后,再通过该对象调用属性对应的方法
   itcastAnnotation ita=(itcastAnnotation)AnnotationTest.class.getAnnotation(itcastAnnotation.class);
   System.out.println(ita.color());
可以认为上面的@itcastAnnotation是itcastAnnotation类的一个实例对象
为属性指定缺省值:String color() default "blue";
value属性:
String value() default "wangli";
如果注解中有一个名称为value的属性,且只想设置value属性(即其他属性都采用默认值或者只有一个value属性),可以省略“value=”部分,如:@itcastAnnotation

("wangli")。
数组类型的属性
int[] array() default{1,2,3};
@itcastAnnotation(array={4,5,6});
如果数组属性中只有一个元素,这时候属性值部分可以省略大括号
枚举类型的属性
enumTest.TrafficLamp lamp();
@itcastAnnotation(lamp=enumTest.TrafficLamp.RED)
注解类型的属性
MetaAnnotation metaAtt() default @MetaAnnotation("wangli");
@itcastAnnotation(metaAtt=@MetaAnnotation("abc"))
可以认为@itcastAnnotation是itcastAnnotation累的一个实例对象,@MetaAnnotation是MetaAnnotation类的一个实例对象。
 

具体实例:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface itcastAnnotation {
 String color() default "blue";
 String value();
 int[] array() default {1,2,3};
 eunmTest.TrafficLamp lamp() default eunmTest.TrafficLamp.RED;
 MetaAnnotation matt() default @MetaAnnotation("123");
}

public @interface MetaAnnotation {
 String value();
}

/*也可以写为@itcastAnnotation("abc"),因为color为缺省属性,可以将value=去掉*/
@itcastAnnotation(matt=@MetaAnnotation("111"),color="red",value="abc",array={4,5,6})
public class AnnotationTest {

 /**
  * @param args
  */
 @SuppressWarnings("deprecated")
 @itcastAnnotation("123")
 public static void main(String[] args) throws Exception{
  // TODO Auto-generated method stub
  System.runFinalizersOnExit(true);
  
  if(AnnotationTest.class.isAnnotationPresent(itcastAnnotation.class)){
   itcastAnnotation ita=(itcastAnnotation)AnnotationTest.class.getAnnotation(itcastAnnotation.class);
   System.out.println(ita.color());
   System.out.println(ita.value());
   System.out.println(ita.array().length);
   System.out.println(ita.lamp().nextLamp().name());
   System.out.println(ita.matt().value());
  }
 }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
08-10
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值