`

黑马程序员Java培训和Android培训Java技术二

 
阅读更多
黑马程序员
二十一
字节码用等号比。
作业:将任意一个对象中的所有String类型的成员变量所对应的字符串内容中的"b"改为"a"。
关键代码:
private static void changeStringValue(Object obj ) throws Exception
  {
       Field [] fields=obj.getClass().getFields();
       for(Field field : fields)
{  
   if(field.getType()==String.class)
    {  
      String oldValue=(String)field.get(obj);
      String newValue=oldValue.replace('b','a');
      //System.out.println("zzz");
      field.set(obj, newValue);
     }
}
   
   }

二十二
Method类
Method类代表某个类中的一个成员方法
得到类中的某一个方法:
例子:Method charAt=Class.forName("java.lang.String").getMethod("charAt",int.class);
调用方法:
通常方式:System.out.println(str.charAt(1));
反射方法:System.out.println(charAt.invoke(str,1));
如果传递给Method对象invoke()方法的第一个参数为null,这有着什么样的意义呢?说明该Method对象对应的是一个静态方法!
jdk1.4和jdk1.5的invoke方法的区别:
Jdk1.5:public Object invoke(Object obj,Object...args)
Jdk1.4:public Object invoke(Object obj,Object[] args),即按jdk1.4的语法,需要将一个数组作为参数传递给invoke方法时,数组中的每个元素分别对应被指定的类型。

二十三
用反射方式执行某个类中的main方法(按下F2出现完整的类名)
目标:
写一个程序,这个程序能够根据用户提供的类名,去执行该类中的mai方法。用普通方式调用后即类名.main(new String[]{"xxx"})的方式。
问题:
启动Java程序的main方法的参数是一个字符串数组,即public static void main(String[] args),通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?按jdk1.5的语法,整个数组是一个参数,而按jdk1.4的语法,数组中的每个元素对应一个参数,当把一个字符串数组作为参数传递给invoke方法时,javac会到底按哪种语法进行处理呢?jdk1.5肯定要兼容jdk1.4的语法,会按1.4的语法进行处理,即把数组打散成为若干个单独的参数。所以,在给main方法传递参数时,不能使用代码mainMethod.invoke(null,new String[]{"xxx"}),javac只把它当作jdk1.4的语法进行理解,而不把它当作jdk1.5的语法解释,因此会出现参数类型不对的问题。
解决办法:
mainMethod.invoke(null,new Object[]{new String[]{"xxx"}});
mainMethod.invoke(null,(Object)new String[]{"xxx"});,编译器会作特殊处理,编译时不把参数当作数组看待,也就不会把数组打散成若干个参数了。或者将参数强制转换成为Object对象。

二十四
数组的反射
具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。
代表数组的Class实例对象的getSuperClass()方法返回的父类的Object类对应的Class。
基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用,非基本类型的一维数组,既可以被当作Object类型使用,也可以当作Object[]类型使用。
Arrays.aList()方法处理int[]和String[]时的差异。不能打印出int[],只能打印出String[]。

二十五
Array工具类用于完成对数组的反射操作。
思考题:怎么得到数组中的元素类型?没有办法得到。但是可以将每个元素单独拿出来来得到该数组的类型。

二十六
ArrayList与hashSet
ArrayList是一种有顺序的集合,有位置顺序。而HashSet是在将对象放入它里面时,先比较里面是否有那个对象,如果有则不再重复放入;如果非要放入,则要先将存在的对象删除掉,再放入。

二十七
反射的作用--->实现框架功能
框架与框架要解决的核心问题
我做房子卖给用户住,由用户自己安装门窗和空调,我做的房子就是框架,用户需要使用我的框架,把门窗插入进我提供的框架中。框架与工具类有区别,工具类被用户的类调用,而框架则是调用用户提供的类。

框架要解决的核心问题
我在写框架( 房子)时,你这个用户可能还在上小学,还不会写程序呢?我写的框架程序怎样能调用到你以后写的类(门窗)呢?
因为在写才程序时无法知道要被调用的类名,所以,在程序中无法直接new某个类的实例对象了,而要用反射方式来做。

综合案例
先直接用new语句创建ArrayList和HashSet实例对象,演示用eclipse自动生成ReflectPoint类的equals和hashcode方法,比较两个集合的运行结果差异。
然后改为采用配置文件加反射的方式创建ArrayList和HashSet的实例对象,比较观察运行结果差异。引入了eclipse对资源文件的管理方式的讲解。

二十八
用类加载器的方式管理资源和配置文件
配置文件的路径要使用绝对路径。使用getRealPath()方法来得到绝对路径。一定要记住用完整的路径,但完整的路径不是硬编码,而是运算出来的。

类加载器:类名.class.getClassLoader().getResourceAsStream(name)name要写出配置文件的路径和配置文件名称。或者使用 类名.class.getResourceAsStream(name)name直接使用配置文件名称。
以后学到的框架用户配置文件都是放在ClassPath中的。

二十九
IntroSpector-->操作JavaBean-->JavaBean是一个特殊的Java类
例如:
class Person
{
  private int x;
  public int getAge()
   {
     return x;
   }
   public void setAge(int age)
   {  this.x=age}
}
以上的Person类有一个JavaBean式的属性是age;命名规则如果第二个字母是小写的,则把第一个字母变成小的。

例如:
gettime-->time
setTime-->time
getCPU--> CPU



内省-->了解JavaBean
JavaBean是一种特殊的Java类,主要用于传递数据信息,这种java类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。
如果要在两个模块直接传递多个信息,可以将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象,则需要通过一些相应的方法来访问,大家觉得这些方法的名称叫什么好呢?JavaBean的属性是根据其中的setter和getter方法来确定的,而不是根据其中的成员变量。如果方法名为setId,中文意思即为设置id,至于你从哪个变量上取,用管吗?去掉set前缀,剩余部分就是属性名,如果剩余部分的第二个字母是小写的,则把剩余部分的首字母改成小写的。(如上例子所说,部分原因是为了识别方便)。总之,一个类被当作javaBean使用时,JavaBean的属性是根据方法名推断出来的,它根本看不到java类内部的成员变量。

一个符合JavaBean特点的类可以当作普通类一样进行使用,但把它当作JavaBean用肯定需要带来一些额外的好处,我们才会去了解和应用JavaBean!好处如下:
1在JavaEE开发中,经常要使用到JavaBean。很多环境就要求按JavaBean方式进行操作,别人都这么用和要求这么做,那你就没什么挑选的余地!
2JDK中提供了对JavaBean进行操作的一些API,这套API就称为内省。如果要你自己去通过getX方法来访问私有的x,那怎么做?用内省这套api操作JavaBean比用普通类的方式更方便。


三十
内省综合案例(可以利用鼠标右键Refactor来抽取某几行代码组成的方法)
演示用eclipse自动生成ReflectPoint类的setter和getter方法。
直接new一个PropertyDescription对象的方式来让大家了解JavaBean API的价值,先用一段代码读取JavaBean的属性,然后再用一段代码设置JavaBean的属性。
演示用eclipse将读取属性和设置属性的流水帐代码分别抽取成方法:
---调用这个方法,并给这个方法传递了一个对象,属性名和设置值,它就能完成属性修改的功能。
---得到BeanInfo最好采用"obj.getClass()",而不要采用"类名.class"方式,这样程序更通用。
采用遍历BeanInfo的所有属性方式来查找和设置某个RefectPoint对象的属性。在程序中把一个类当作JavaBean来看,就是调用IntroSpector.getBeanInfo方法,得到的Beaninfo对象封装了把这个类当作JavaBean看的结果消息。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics