java基础加强(11~28)

 ----------------------   ASP.Net+Android+IOS开发.Net培训、期待与您交流! -----------------------
1. 享元设计模式  flyweight
     很多小的对象有很多相同的属性,那就可以把他们变成一个对象,那些不同的部分把它变成外部属性,作为方法的参数传入,称之为外部装态,那些相同的属性称之为内部状态。
 
2. 枚举
     枚举就是要让某个类型的变量的取值只能为若干个固定值中的一个,否则,编译器就会报错。
     作用:枚举可以让编译器在编译时就可以控制源程序中填写的非法值,普通变量的方式在开发阶段无法实现这一目标。
 
     用抽象类模拟枚举功能,如采用抽象方法nextDay就将大量的if else语句转移成了一个个独立的类。
 
     枚举内部定义的所有信息必须位于元素列表之后。且元素列表后须有分号。
     枚举类的构造方法是私有的。
 
     如果枚举只有一个成员,就可以作为单列的实现。
 
     子类调用父类有参的构造方法,如new Date(100){};
 
3. 反射---->反射就是把java中的各中成分映射成相应的类(反射会降低效率)
     3.1 静态方法:forName的作用:返回字节码,有两种情况:
          1. 字节码已经存在于内存中,直接返回。2.字节码在内存中不存在,先加载进内存,再返回
     3.2任何类型都有且只有一份其对应的Class实例对象,包括基本类型和数组 
          int.class == Integer.TYPE//true; int.class == Integer.class//false
  
     3.3用反射获取实列对象时,需用两个参数
          1.在获取构造方法时,要传入参数的类型  2.用得到的方法去创建对象时,要传入同样类型的对象
 
     3.4 Field fieldY = p.getClass().getField("y"); // fieldY不是对象身上的值,而是类上,需要用它去取某个对象上对应的值fieldY.get(p);
  
          对于私有的属性,需要用setAccessible(true)设置后才能在相应对象上获取值,这就是暴力反射
 
     3.5 如果传递给invoke()方法的第一个参数为null,那么该Method对象对应的方法是一个静态方法
          1. 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方法时,数组中的每个元素分别对应被调用方法中的一个参数,
               所以,调用charAt方法的代码也可以用Jdk1.4改写为 charAt.invoke(“str”, new Object[]{1})形式。
         2. 为什么要用反射的方法调用main方法?
             在写程序的时候不知道要执行那个类,在运行程序时,可以通过给main传递参数的形式将要执行的类名传递进去,然后通过反射获取传递类的字节码,进而实现动态执行所需要运行的类。
        3. 问题
              启动Java程序的main方法的参数是一个字符串数组,即public static void main(String[] args),通过反射方式来调用这个main方法时,如何为invoke方法传递参数呢?按jdk1.5的语法,整个数组是一个参数,而按jdk1.4的语法,数组中的每个元素对应一个参数,当把一个字符串数组作为参数传递给invoke方法时,javac会到底按照哪种语法进行处理呢?
              jdk1.5肯定要兼容jdk1.4的语法,会按jdk1.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"}); 
          编译器会作特殊处理,编译时不把参数当作数组看待,也就不会数组打散成若干个参数了 
   
      4. 数组定义时如果指定了元素,就不能在指定长度了,如int[] arr = new int[2]{1,2}将会报错
            Arrays.asList(T...):将基本类型的数组作为参数传递进去的时候,整个数组作为一个对象进行转换(jdk1.5),即得到的集合只有一个元素,将非基本类型的数组作为参数传递进去的时候,数组的每一个元素都将作为一个对象进行转换(jdk1.4).
  
     5. 具有相同维数和元素类型的数组属于同一个类型,即具有相同的Class实例对象。
           代表数组的Class实例对象的getSuperClass()方法返回的父类为Object类对应的Class。
           基本类型的一维数组可以被当作Object类型使用,不能当作Object[]类型使用;
           非基本类型的一维数组,既可以当做Object类型使用,又可以当做Object[]类型使用。
           
     6. Array工具类对数组的反射操作:
          private static void printObject(Object obj) {
                Class clazz = obj.getClass();
                if(clazz.isArray()){
                     int len = Array.getLength(obj);
                     for(int i=0; i<len; i++){
                          System.out.println(Array.get(obj, i));
                     }
                }else{
                        System.out.println(obj);
                }
           }
       怎么得到数组中的元素类型?
              不能得到数组中元素的类型,因为Object数组可以存放不同类型的元素,但是可以得到数组中某一个元素的类型
 
 3.6 内存泄漏:一个对象不用了,但是它一直占用内存空间,没有被释放。
      
      通常来说,一个对象的两个实例对象用equals比较相同时,他们用hashCode比较也应该相同,反之则不然。
      通常要求写类的时候将hashCode和equals方法一并覆盖,说不定什么时候就用上了,但是一个对象如果确定不会被存到hash集合里面,是不需要覆盖hashCode方法的。
      当一个对象呗存进HashSet集合后,就不能修改对象中那些参与hashCode计算的字段了,否则,对象修改后的哈希值与最初存进HashSet集合的哈希值就不同了,在这种情况下,即使contains方法使用该对象的引用作为参数去HashSet集合中检索对象,也会返回找不到该对象的结果,这也会导致无法从HashSet集合中单独删除该对象,从而造成内存泄漏。
 
 3.7 InputStream ips = new FileInputStream("config.properties");// 一定要用完整的路径,但完整的路径不是硬编码,而运算出来的。
  
   用类加载器管理资源和配置文件
  1. InputStream ips = RedlectTest.class.getClassLoader().getResourceAsStream("reflecttest/config.properties");
  2. InputStream ips = RedlectTest.class.getResourceAsStream("config.properties");//配置文件位于classpath路径下
  3. InputStream ips = RedlectTest.class.getResourceAsStream("/reflecttest/resource/sconfig.properties");//配置文件位于classpath的resources下
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值