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:   
原文地址:https://www.cnblogs.com/94007boy/p/2690188.html