zoukankan      html  css  js  c++  java
  • JAVA高新技术学习<一>

    (jdk1.5新特性:枚举,注解,泛型)

    高新技术知识点:

    1.可变参数和增强for循环

        /**可变参数的特点:
        *...只能出现在参数列表最后面
        *位于变量类型和变量名之间,前后无空格都可以
        *调用可变参数方法时,编译器为该可变参数创建隐含数组,
        *注意:它只为可变参数创建数组,上面的int x不在可变参数中,所以x不在可变参数中
        *把int x删掉,则所有参数均纳入数组中
        *在方法体中以数组形式访问可变参数。
        */

       1:  package Itcast.com;
       2:  //import static java.lang.Math.max;//必须是静态导入
       3:  //import static java.lang.Math.abs;//要加static
       4:   
       5:  public class zhang01 
       6:  {
       7:      public static void main(String[] args)
       8:      {
       9:          add(3,5,6);
      10:      }    
      11:      public static void add(int... args)//可变参数
      12:      
      13:      {        
      14:          //这里sum=0是错的,一开始是第一个值
      15:           /*
      16:           for (int i=0;i<args.length;i++)//这里犯过低级错误for条件体之间是用;   隔开
      17:           {
      18:               sum+=args[i];
      19:           }             
      20:               return sum;
      21:           */
      22:           //加强for循环(迭代取值)
      23:           //格式:for(type 变量名:集合变量的名字){}    
      24:           int sum=0;
      25:           for(int arg:args)//自定义变量arg,用arg去迭代集合agrs,用arg逐一去取args里的元素                         
      26:           {
      27:               System.out.println(arg);
      28:               sum+=arg;
      29:           }
      30:           System.out.println(sum);     
      31:      }
      32:   
      33:  }
      34:  //overload 重载
      35:  //override 重写

    2.自动拆装箱和享元设计模式

    /*享元模式(设计模式)
    * 有很多个小的对象,他们有很多属性相同,所以把他们变成一个对象,
    * 那些不同的属性把他们变成方法的参数。
    * 将基本数据类型数字装箱时,如果在其在一个字节之内(-128到127)
    * 由于位于常用区域不会改变,所以将其缓存起来,下次可直接拿来用   
    * 没必要一个数字对应多个对象     公用即可         *
    */

    package Itcast.com;
    
    public class AutoBox 
    {
        public static void main(String[] args)
        {        
            Integer iobj=125;
            Integer jobj=125;
            System.out.println(iobj==jobj);    
            /**
             *          
             */
        }
    
    }

    3.枚举

          3.1 用普通类模拟实现枚举功能

       1:  package Itcast.com;
       2:  public abstract class WeekDay1 
       3:  {    
       4:      private WeekDay1(){}//私有的构造方法    
       5:   
       6:      
       7:      /*定义外部类的抽象方法
       8:       */
       9:      public abstract WeekDay1 nextDay();
      10:      
      11:      //每个元素分别用一个公有的静态成员表示
      12:      
      13:      /*现在想要在这个抽象类WeekDay1里面创建枚举类型的对象,就不能直接用new了,因为是抽象类不可以
      14:       *只能用这个类的子类来创建对象 ,但这个子类必须要复写父类的所有抽象方法才可以 
      15:       *把本来大量的if else 语句转为了一个个独立的类(内部类)
      16:       */
      17:      public final static WeekDay1 SUN=new WeekDay1(){//用匿名内部类去复写抽象方法        
      18:          public WeekDay1 nextDay()
      19:          {
      20:              return MON;    
      21:          }
      22:      };
      23:      //通过匿名内部类复写父类抽象方法后,成功创建了抽象类的对象  
      24:      public final static WeekDay1 MON=new WeekDay1()
      25:      {
      26:          public WeekDay1 nextDay()
      27:          {
      28:              return SUN;    
      29:          }
      30:      };
      31:      /*public WeekDay nextDay()
      32:      {
      33:          if(this==SUN)
      34:          {
      35:              return MON;            
      36:          }
      37:          else
      38:          {
      39:              return SUN;
      40:          }
      41:      }*/
      42:      
      43:      
      44:      //对象创建完成,把对象的返回值类型转成字符串 ,便于打印结果
      45:      public String toString()
      46:      {
      47:          return this==SUN? "SUN":"MON";
      48:      }
      49:    
      50:  }

          

         3.2 定义一个正规的枚举用enum关键字实现,演示规范的枚举定义

       1:  package Itcast.com;
       2:   
       3:  public class EnumTest//枚举
       4:  /*定义类型,让这些类型的变量指向的指是指定的值
       5:   * 演示用普通类实现枚举的方法,如下
       6:   */
       7:  {
       8:      public static void main(String[] args)
       9:      {
      10:          //自定义枚举
      11:          WeekDay1 weekDay = WeekDay1.MON;
      12:          System.out.println(weekDay.nextDay());
      13:          
      14:          //利用专业枚举演示:
      15:          WeekDay  weekDay2= WeekDay.FRI;
      16:          System.out.println(weekDay2.name());
      17:          //返回指定对象在枚举元素中的位置,从0开始计数
      18:          System.out.println(weekDay2.ordinal());
      19:          //把别人传过来的字符串变成一个实际的星期对象
      20:          System.out.println(weekDay2.valueOf("SUN"));
      21:          //返回一个数组,把枚举里面的元素都装进数组,还可以对数组
      22:          //进行操作
      23:          System.out.println(weekDay2.values().length);    
      24:          System.out.println(TrafficLamp.GREEN.time);
      25:      }
      26:      /*
      27:       * 定义一个正规的枚举用enum关键字实现
      28:       */
      29:      //可以给枚举自定义    
      30:      public enum WeekDay    
      31:      {
      32:          //静态的成员变量,执行后都会初始化
      33:          //枚举的元素必须写在所有成员最前面,注意!!
      34:           SUN(1),MON(),TUE(1),WED,THI,FRI,SAT;
      35:           /*如下面所示,给出两个构造函数,一个没参数,一个带int类型的参数
      36:            * 那么初始化的时候到底构造谁呢?
      37:            * 在上面的元素列表中元素后面加(),如果里面有int值,则调用
      38:            * 带参数的构造方法传入相应参数来构造对应的元素,没值则调用空参数的那个来构造
      39:            * 对应的元素
      40:            * 即实现元素的差别化构造      
      41:            */
      42:           //构造方法必须是私有的,而且必须位于元素列表之后
      43:           private WeekDay()
      44:           {
      45:               System.out.println("first");
      46:           }
      47:           private WeekDay(int day)
      48:           {
      49:               System.out.println("second");
      50:           }
      51:      }
      52:      //定义一个交通灯枚举类,他有三个元素:红绿黄
      53:      public enum  TrafficLamp    
      54:      {            
      55:          RED (30)
      56:          { 
      57:              public     TrafficLamp nextLamp()
      58:              {
      59:                   return GREEN;
      60:              }
      61:          },
      62:          GREEN(45)
      63:          { 
      64:                  public     TrafficLamp nextLamp()
      65:                  {
      66:                  return YELLOW;
      67:                  }    
      68:          },
      69:          YELLOW(5)
      70:          {
      71:                  public     TrafficLamp nextLamp()
      72:                  {
      73:                       return RED;
      74:                  }
      75:          };
      76:          //每个元素通过内部类都复写了父类的抽象方法得以建立对象
      77:          //很重要的一点,枚举元素是写在所有成员(变量、函数)的最前面的。
      78:          public  abstract TrafficLamp nextLamp();
      79:          //成员变量time,通过构造函数可以给每个元素赋予相应的time值
      80:          private int time;
      81:          //这样子类就会调用父类有参的构造方法
      82:          private TrafficLamp(int time) 
      83:          {
      84:              this.time=time;
      85:          }
      86:          
      87:          
      88:      }
      89:    
      90:   
      91:  }

    4.反射

    /**
    * 反射的基石  Class类
    * 用于描述java程序中用到的各个java类,他们的共性就是
    * 他们都是java中的类,所以可以用Class类来描述
    * Class类不能直接用new来创建对象,他是一堆类的字节码
    * 定义方法
    * Class clas1=Date.class//得到相应类的字节码
    * 拥有的方法:
    * p1.getClass():得到对象所属的那份字节码
    * 类的静态方法forName:
    * 返回字节码文件:1.已加载到虚拟机中的,直接返回该字节码
    *   2.虚拟机里没有,用类加载器加载并缓存到虚拟机再返回该字节码
    * Class.forName("java.lang.String")
    * 得到各个字节码对应的实例对象(Class类型)
    * 1 类名.class
    * 2 对象.class
    * 3 Class.forName("类名") 
    * 八个基本数据类型加void预定义了Class实例对象
    * @author shantui
    * 反射就是把java类中的各种成分映射成相应的java类   
    * 反射的constructor类:得到某个类所有的构造方法
    */

    先自定义一个反射点

       1:  package Itcast.com;
       2:   
       3:  public class ReflactPoint
       4:  {
       5:     /* 
       6:      private int x;
       7:      public int y;
       8:      ReflactPoint(int x,int y)
       9:      {
      10:          this.x=x;
      11:          this.y=y;
      12:      } 
      13:      */
      14:      
      15:      public String str1="ball";
      16:      public String str2="basketball";
      17:      public String str3="fbbtball";
      18:      //反射点    
      19:   
      20:      public String toString() 
      21:      {
      22:          return str1+";"+str2+";"+str3;
      23:      }
      24:      
      25:      
      26:      //选中x,然后alt+shif+s:快速产生构造方法
      27:      
      28:      
      29:  }

    4.1 对构造方法、自定义方法、数组的反射演示

       1:  package Itcast.com;
       2:   
       3:  //import java.lang.reflect.Constructor;
       4:  import java.lang.reflect.Array;
       5:  import java.lang.reflect.Field;
       6:  import java.lang.reflect.Method;
       7:  import java.util.Arrays;
       8:  public class reflect
       9:  {
      10:      public static void main(String[] args)throws Exception
      11:      {
      12:          String str1="abc";    
      13:          /**            
      14:          Class cls1=str1.getClass();
      15:          //Class cls2=String.class;
      16:          //Class cls3=Class.forName("java.lang.String");
      17:          //System.out.println(cls1==cls2);
      18:          //System.out.println(cls3==cls2);
      19:          //验证是不是个基本数据类型的字节码
      20:          //结果是否,因为他是个类
      21:          //System.out.println(cls1.isPrimitive());
      22:          //int是基本数据类型
      23:          //System.out.println(int.class.isPrimitive());
      24:          //问:int[]这个类型是不是数组类型
      25:          //结果:是这样判断的
      26:          //System.out.println(int[].class.isArray());        
      27:  
      28:          //constructor构造器类型,方法使用:        
      29:  
      30:  
      31:          //得到String类中指定构造方法,哪个呢(有很多个构造方法而且无序)?
      32:          //我只想得到构造方法中:接受参数为两个,分别是StringBuffer类型,int类型
      33:          //只想得到这种,如何得到,如下:
      34:          //Constructor    constructor1= String.class.getConstructor(StringBuffer.class,int.class);
      35:  
      36:          //用反射实现此效果:new String (new StringBuffer("abc")),就是给String的构造函数传入的是一个abc,这个abc是个StringBuffer类型,以此完成new一个String
      37:          //重新对StringBuffer进行自定义的构造
      38:          //编译期不执行等号右边的运算,所以不知道constructor是谁的构造方法,返回的是谁的,所以要指明
      39:          //不指明编译期通不过的
      40:          //Constructor    constructor2= String.class.getConstructor(StringBuffer.class);
      41:          //得到构造方法后,怎么用?:有一个newInstanc方法:构造一个实例对象。
      42:          //String str2=(String)constructor2.newInstance(new StringBuffer("abc"));
      43:          //System.out.println(str2.charAt(2));
      44:          //创建一个对象的一般方法class->constructor-->new object 
      45:          //为简化过程,用到了newInstance:创建一个实例对象:Class.newInstance    
      46:  
      47:          //给反射点传入两个值
      48:           * 
      49:           */
      50:          ReflactPoint pt1=new ReflactPoint();
      51:          /**得到一个类身上的某个字段                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
      52:          Fied类代表某个类中的一个成员变量,即 成员变量类
      53:          filedy的值不是5,因为filedy不是对象身上的变量,而是类上的,要用它 去取x和Y
      54:          他把类上的指定的成员变量封装起来,成为类里的一个变量,可用他去取值
      55:          Field fieldy = pt1.getClass().getField("y");        
      56:          System.out.println(fieldy.get(pt1));
      57:          由于 x私有了,要想得到x,需要用getDeclaredField("x")
      58:          Field fieldx = pt1.getClass().getDeclaredField("x");
      59:          把私有的x进行暴力反射
      60:          fieldx.setAccessible(true);
      61:          System.out.println(fieldx.get(pt1));
      62:          */
      63:          changeStingValue(pt1);
      64:          System.out.println(pt1);
      65:          /**
      66:                  通过反射调用Sting类型的CharAt()方法
      67:                  得到String类文件中的指定方法,即名字为charat,接受的数据类型为int类型的那个重载形式
      68:                  这里的名字一定要是系统存在的函数名,而且不要写错,比如首字母是小写的。        
      69:           */
      70:          Method methodCharAt =String.class.getMethod("charAt",int.class);
      71:          /**
      72:          invok:调用,他是方法身上的调用,即方法的开启标志和信号 
      73:          invok格式:invok(要用charAt的变量名称,你要charAt第几个?)
      74:          如果出现这样的格式:invok( ,x),说明该Method方法,这是个静态方法        
      75:          */
      76:          System.out.println(methodCharAt.invoke(str1,1));
      77:          
      78:          /**
      79:           * TestArguments.main(new String[]{"abc","ddd"});
      80:                  如果要启用的TestArguments这个类是客户输入的,我们不知道,则上面的方法不可行了 
      81:                 为什么要用反射调用main,假如TestArguments中,每个args[i]都是个类名,我们不知道客户想运行哪个类的主函数
      82:                  这是就要用到反射,给我你想运行的类名,我反射一下就可以执行其主函数
      83:          */
      84:          
      85:          /**
      86:           * 这里调出软件的run as对话框,把此主函数入口中要传入的(x)=Arguments
      87:           * 这样这个主函数就会被传入一个类类型的变量,相当于客户输入了一个类,
      88:           * 让本类来运行他的主函数         * 
      89:           */
      90:          String startingClassName=args[0];
      91:          Method mainMethod =Class.forName(startingClassName).getMethod("main", String[].class);
      92:          
      93:          mainMethod.invoke(null,(Object)new String[]{"abc","123","sss"});
      94:          /*
      95:           * 数组反射演示:
      96:           */
      97:          int [] a1=new int[]{1,2,3};
      98:          int [] a2=new int[4];
      99:          int [][] a3=new int[1][2];
     100:          String [] a4=new String[]{"111","2222","3"};
     101:          System.out.println(a1.getClass()==a2.getClass());
     102:          System.out.println(a1.getClass().getName());//“[I”代表 :整数 数组
     103:          System.out.println(a1.getClass().getSuperclass().getName());//数组父类名
     104:          
     105:          /*
     106:           * 基本数据类型都不是Object类型
     107:           * 所以Object[] aobj1=a1是错的,int不是Object类型,int[]是
     108:           */
     109:          Object[] aobj4=a4;//String是Object类型
     110:          Object[] aobj3=a3;
     111:          /**
     112:          object数组内装了一个abject类型的数组,即二维数组。
     113:          aslist方法可以把字符串数组的元素转成List集合的形式,但它只接受Object类型的数组
     114:          ,但int类型数组不符合,所以只把a1当成一个单纯Object数处理。        
     115:           */
     116:          System.out.println(Arrays.asList(a1));
     117:          System.out.println(Arrays.asList(a4));
     118:      //数组反射演示:
     119:          Object obj =null;
     120:          printObject(a4);    
     121:          
     122:      }
     123:      
     124:      private static void printObject(Object obj)
     125:      {
     126:          // TODO Auto-generated method stub
     127:          Class clasz=obj.getClass();
     128:          if (clasz.isArray()) 
     129:          {
     130:              int len =Array.getLength(obj);
     131:              for (int i = 0; i <len; i++) 
     132:              {
     133:                  System.out.print(Array.get(obj, i)+" ");
     134:              }
     135:          }
     136:          else
     137:          {
     138:              System.out.println(obj);
     139:          }        
     140:      }
     141:   
     142:   
     143:   
     144:   
     145:   
     146:      //把指定成员变量的值按照指定的规则替代(把b全换成a)
     147:          private static void changeStingValue(Object obj) throws Exception
     148:      {
     149:          // TODO Auto-generated method stub
     150:          Field[] fields =obj.getClass().getFields();
     151:          for(Field field :fields)
     152:          {
     153:              //字节码的比较用等号,因为都只有一份
     154:              //if(field.getType().equals(String.class))
     155:              if(field.getType()==String.class);
     156:              {
     157:                  String oldvalue=(String)field.get(obj);
     158:                  String newValue= oldvalue.replace('b', 'a');
     159:                  field.set(obj, newValue);    
     160:                  
     161:              }
     162:          }
     163:          
     164:      }    
     165:  }
     166:   
     167:  class TestArguments//等待客户输入此类
     168:  {
     169:      public static void main(String[] args) 
     170:      {
     171:          for(String arg: args)
     172:          {
     173:              System.out.println(arg);
     174:          }
     175:          
     176:      }
     177:  }

       4.2 用对类的反射实现客户给我什么类,我就运行什么类的效果

    /*获取类的方法2:类加载器       
    * 配置文件都放在classpath指定的目录下。
    * 获取类的方法1:通过配置文件:
    * 通过集合框架的形式,传入指定的集合类型,可将下面的
    * 集合类定义成用户传入的 类,这里就需要传入一个配置文件“config.properties”
    * 在里面预先写入想传入的是哪个集合类

       1:  package Itcast.com;
       2:  import java.io.FileInputStream;
       3:  import java.io.InputStream;
       4:  import java.util.Collection;
       5:  import java.util.Properties;
       6:  public class ReflectTest2 
       7:  {
       8:      public static void main(String[] args) throws Exception 
       9:      {
      10:          
      11:          //获得ReflectTest2类的类加载器后到classpath指定的目录中去加载指定的类,
      12:          ReflectTest2.class.getClassLoader().getResourceAsStream("E:/lsk/studyTest//config.properties");
      13:          
      14:          //读取配置文件
      15:          InputStream ips =new FileInputStream("config.properties");
      16:          //利用properties类加载读取的配置文件中的信息
      17:          Properties props =new Properties();
      18:          props.load(ips);
      19:          ips.close();
      20:          //按照配置文件中的类名,找到其值(类的类型),即由其key找到其value(集合类型),赋给className
      21:          String className = props.getProperty("className");
      22:          //按照类名(key=className)找到对应类类型(value)后新构造一个collections
      23:          Collection collections =(Collection)Class.forName(className).newInstance();
      24:          
      25:          //Collection collections =new HashSet();
      26:          person p1=new person(5,5);
      27:          person p2=new person(5,5);
      28:          person p3=new person(3,3);
      29:          collections.add(p1);
      30:          collections.add(p2);
      31:          collections.add(p3);
      32:          collections.add(p1);
      33:          System.out.println(collections.size());
      34:      }
      35:  }
      36:  class person
      37:  {
      38:      int x=0,y=0;
      39:      person(int x,int y)
      40:      {
      41:          this.x=x;
      42:          this.y=y;
      43:      }
      44:      
      45:  }
      46:   
  • 相关阅读:
    Android实现通过浏览器点击链接打开本地应用(APP)并拿到浏览器传递的数据(转)
    保存图片文件到本地
    android ScrollView中嵌套GridView,ListView只显示一行的解决办法
    蒙版提示页(添加新功能后的一种提示)
    C和指针 第三章--数据
    *(ptr++) += 123
    优先级队列-堆
    单链表相关(一)
    字符间的距离-动态规划
    和最大的连续子数组
  • 原文地址:https://www.cnblogs.com/94007boy/p/2690188.html
Copyright © 2011-2022 走看看