黑马程序员07_基础加强01

来源:互联网 发布:淘宝卖家退款要验证码 编辑:程序博客网 时间:2024/05/21 20:28

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------

可变参数、自动装箱拆箱、字符串池、枚举、Class、反射

1、可变参数:适用于参数个数不确定,类型确定的情况。

注意:可变参数出现在参数列表的最后, ...  位于变量类型和变量名之间,前后有无空格都可以。 

可以把可变参数看成是一个数组来使用

package com.itheima.xiaozhi;    public class VariableParameter {        //可以把可变参数看成是一个数组      public static void main(String[] args) {          System.out.println(add(1,2,3,4));          System.out.println(add(1, new int[] {2,3,4}));      }            public static int add(int a, int...args) {//int[] args          for (int i = 0; i < args.length; i++) {              a+=args[i];          }          return a;      }  }  

将一个数组赋给一个可变参数,通常采用的原则是[拆]

比如将new String[ ]{ "1",  "2",  "3"} 赋给String ... strs,是先将String数组拆成三个字符串“1”,“2”,“3”,然后对应赋给可变参数

但是如果将一个int类型的数组赋给可变参数类型Object ... os,采用的原则也是拆吗?

看下面代码

package com.xiaozhi.hellotest;    public class Test {        public static void main(String[] args) {          int[] a=new int[]{1,2,3};          System.out.println( a instanceof Object);      }  }  

这两行代码说明int[ ]属于Object的实例,一个简单类型的数组属于一个Object实例,那么将一个简单类型数组赋给Object ... os 可变参数,其实就想当于传了一个Object对象参数而已。所以采用的原则不是拆了。

下面代码页可以证明这一点

package com.itheima.xiaozhi;    import java.util.Arrays;  import java.util.List;    public class VariableParam {        public static void main(String[] args) {          // public static <T> List<T> asList(T... a)(Object[]os)          List list = Arrays.asList("1", "2", "3");          System.out.println(list);// [1, 2, 3]            String arr[] = { "1", "2", "3", "4" };          list = Arrays.asList(arr);          System.out.println(list);// [1, 2, 3, 4]            Integer nums2[] = { 1, 2, 3, 4, 5 };          list = Arrays.asList(nums2);          System.out.println(list);// [1, 2, 3, 4, 5]                    int nums[] = { 1, 2, 3, 4, 5 };          list = Arrays.asList(nums);          System.out.println(list.size());//1          System.out.println(list);// [[I@120d62b]        }  }  

2、基本数据类型的自动装箱和拆箱:基本数据类型和它所对应的包装类可以自动转换

比如Integer  i =  1;1自动装箱成为Integer类型

int j = i+1;  i自动拆箱成int类型与1相加

享元设计模式:

integer i1 =3;

integer i2 =3;

i1 == i2  结果是true

integer i3 =137;

integer i4 =137;

i3 == i4 结果是false

对于小的整数(-128 ~ 127),装箱成为的对象都是同一个对象,这就是享元模式的一个小例子

package com.xiaozhi.box;    public class Test {        public static void main(String[] args) {          //自动装箱          Integer integer1=13;          Integer integer2=13;          //自动拆箱          System.out.println(integer1+2);                    //享元设计模式:对于小的整数,装箱装成的对象都是同一个          System.out.println(integer1==integer2);          Integer integer3=137;          Integer integer4=137;          System.out.println(integer3==integer4);      }  } 

3、字符串池

String s="abc";//放入字符串池,如果池中已经有该字符串,直接使用

String s=new String("abc");//直接新建对象不放入字符串池


4、枚举

枚举类里面的每一个元素都是一个类的实例对象。

枚举类里面的元素必须位于类的里面的所有成分之前。

枚举类的构造方法必须是private私有的。

JDK1.5以后一个枚举类这样写

enum Grade{      A,B,C,D;  }

JDK1.5以前没有枚举类,是这样子做的,构造方法是私有的(只有类内可以创建本类对象)每个对象都是public(公有的,外面可以访问) static (可以通过类名访问)final(不允许改变的)

class Grade{    private Grade(){}    public static final Grade A=new Grade();    public static final Grade B=new Grade();    public static final Grade C=new Grade();    public static final Grade D=new Grade();  } 

也就是说当枚举只有一个元素时,可以作为单列的一种实现方式。

enum Grade{A}
带有抽象方法的枚举类,要在创建枚举类的同时实现抽象方法

下面是示例代码,代码中还有values()方法、valueOf(String str)、ordinal()的使用

package com.xiaozhi.enumration;    public class Test {        public static void main(String[] args) {          for(Grade a:Grade.values())          System.out.println(a.getScore());                  System.out.println(Grade.valueOf("A").getScore());//优                System.out.println(Grade.A.ordinal());//0    }  }    enum Grade{      A("90-100"){          public String getScore(){              return "优";          }      },      B("80-90"){          public String getScore(){              return "良";          }      },      C("70-80"){          public String getScore(){              return "中";          }      },      D("60-70"){          public String getScore(){              return "差";          }      };      private String value;        private Grade(String value) {          this.value = value;      }        public String getValue() {          return value;      }        public void setValue(String value) {          this.value = value;      }            public abstract String getScore();  } 

5、Class:

内存中的每一份字节码就是一个Class类的实例对象

类是用来描述一类事物的共性,比如人这个类的对象有张三李四王五,而Class的对象有Math.class  Data.class  

如果要加载的类字节码已经被加载过,那么第二次加载就返回已经加载在内存中的字节码。

java中有9个预定义的Class实例对象,基本数据类型boolean byte char short int long float double 和关键字void

isPrimitive()可以判断是否是基本数据类型的字节码

package com.xiaozhi.box;    public class Test {        public static void main(String[] args) {                              System.out.println(int.class == Integer.class);          System.out.println(int.class.isPrimitive());//是否是基本数据类型的字节码          System.out.println(int.class == Integer.TYPE);//表示基本数据类型int的class实例      }  } 

6、反射:就是把java类中的各个成分映射成相应的java类

例如,一个java类中用一个Class类的对象来表示,一个类的组成部分:成员变量,方法,构造方法,包等等信息也用一个个的java类来表示,就像汽车是一个类,汽车中的发动机,变速箱等等也是一个个的类。表示java类的Class类显然要提供一系列的方法,来获得其中的变量,方法,构造方法,修饰符,包等信息,这些信息就是用相应类的实例对象来表示,他们是Field、Method、Contructor、Package等等。

要反射的类

package com.xiaozhi.reflect;    import java.io.InputStream;  import java.util.List;    public class Person {        private String name;      private int password;            public Person() {          System.out.println("无参构造函数");      }              public Person(String name) {          this.name = name;          System.out.println("一个参数的构造函数"+name);      }          public Person(String name, int password) {          this.name = name;          this.password = password;          System.out.println("两个参数的构造函数"+name+":"+password);      }            private Person(List list){          System.out.println("私有构造函数");      }                  public void aa1(){          System.out.println("aa1");      }      public void aa1(String name,int password){          System.out.println("name= "+name+" password="+password);      }      public Class[] aa1(String name,int[] password){          return new Class[]{String.class};      }      private void aa1(InputStream in){          System.out.println(in);      }      public static void aa1(int num){          System.out.println(num);      }      public static void main(String []args){          System.out.println("main");      }    }  
加载类的字节码的三种方法

第一种:Class.forName(String str)

第二种:类名.class

第三种:new 类名 .getClass()

反射构造函数调用Class的getConstructor(构造函数的参数的Class对象)

package com.xiaozhi.reflect;    import java.lang.reflect.Constructor;  import java.util.ArrayList;  import java.util.List;      public class Test {        public static void main(String[] args) throws Exception {          //加载类的字节码的三种方法  //      Class clazz=Class.forName("com.xiaozhi.reflect.Person");  //      Class clazz=new Person().getClass();  //      Class clazz=Person.class;                    //无参的构造函数  //      Class clazz=Class.forName("com.xiaozhi.reflect.Person");  //      Constructor constructor=clazz.getConstructor(null);  //      Person person=(Person) constructor.newInstance(null);                    //一个参数的构造函数  //      Class clazz=Class.forName("com.xiaozhi.reflect.Person");  //      Constructor constructor=clazz.getConstructor(String.class);  //      Person person=(Person) constructor.newInstance("jingtianxiaozhi");                    //两个参数的构造函数  //      Class clazz=Class.forName("com.xiaozhi.reflect.Person");  //      Constructor constructor=clazz.getConstructor(String.class,int.class);  //      Person person=(Person) constructor.newInstance("jingtianxiaozhi",100);                    //私有的构造函数  //      Class clazz=Class.forName("com.xiaozhi.reflect.Person");  //      Constructor constructor=clazz.getDeclaredConstructor(List.class);  //      constructor.setAccessible(true);  //      Person person=(Person) constructor.newInstance(new ArrayList());                    //默认的          Class clazz=Class.forName("com.xiaozhi.reflect.Person");          Person p=(Person) clazz.newInstance();      }        }
反射方法

getMethod(方法名 ,方法参数)

获取main方法比较特殊,有两种方法:

第一种:把字符串数组包装在一个Object数组中

第二种:把字符串数组强制转换成Object类型,骗过编译器

package com.xiaozhi.reflect;    import java.io.FileInputStream;  import java.io.InputStream;  import java.lang.reflect.Method;    public class Test2 {        public static void main(String[] args) throws Exception {          //无参的方法          //public void aa1()  //      Class clazz=Class.forName("com.xiaozhi.reflect.Person");  //      Method method=clazz.getMethod("aa1",null);  //      Person person=new Person();  //      method.invoke(person,null);                    //有参数的方法          //public void aa1(String name,int password)  //      Class clazz=Class.forName("com.xiaozhi.reflect.Person");  //      Method method=clazz.getMethod("aa1",String.class,int.class);  //      Person person=new Person();  //      method.invoke(person,"jingtianxiaozhi",22);                    //有返回值的方法          //public Class[] aa1(String name,int[] password)  //      Class clazz=Class.forName("com.xiaozhi.reflect.Person");  //      Method method=clazz.getMethod("aa1",String.class,int[].class);  //      Person person=new Person();  //      Class cs[]=(Class[]) method.invoke(person,"jingtianxiaozhi",new int[]{1,2,3});  //      System.out.println(cs[0]);                    //private void aa1(InputStream in){  //      Class clazz=Class.forName("com.xiaozhi.reflect.Person");  //      Method method=clazz.getDeclaredMethod("aa1",InputStream.class);  //      method.setAccessible(true);  //      Person person=new Person();  //      method.invoke(person,new FileInputStream("c:\\jingtianxiaozhi.txt"));                    //静态方法          //public static void aa1(int num){  //      Class clazz=Class.forName("com.xiaozhi.reflect.Person");  //      Method method=clazz.getMethod("aa1",int.class);  //      method.invoke(null,22);                    //main方法          Class clazz=Class.forName("com.xiaozhi.reflect.Person");          Method method=clazz.getMethod("main", String[].class);          method.invoke(null,new String[]{"13"});//Object...//拆开之后,main方法接受的参数是字符串          method.invoke(null,new Object[]{new String[]{"13"}});//Object...//拆开之后,是一个字符串数组          method.invoke(null,(Object)new String[]{"13"});                          }  } 
反射字段:

getField(字段名)

package com.xiaozhi.reflect;    import java.lang.reflect.Field;    public class Test {        public static void main(String[] args) throws Exception {          //获取公有字段类型字段值  //      Class clazz=Class.forName("com.xiaozhi.reflect.Person");  //      Field field=clazz.getField("name");  //      Class type=field.getType();  //      System.out.println(type);  //      Person person=new Person();  //      String value=(String)field.get(person);  //      System.out.println(value);                    //设置公有字段值  //      field.set(person,"xiaozhi");  //      System.out.println(field.get(person));                    //获取私有字段类型以及值  //      Class clazz=Class.forName("com.xiaozhi.reflect.Person");  //      Field field=clazz.getDeclaredField("password");  //      field.setAccessible(true);  //      Class type=field.getType();  //      System.out.println(type);  //      Person person=new Person();  //      Integer value=(Integer)field.get(person);  //      System.out.println(value);                              //获取静态字段类型以及值          Class clazz=Class.forName("com.xiaozhi.reflect.Person");          Field field=clazz.getField("age");          Class type=field.getType();          System.out.println(type);          Integer value=(Integer)field.get(null);          System.out.println(value);      }  }    class Person{      public String name="aaa";      private int password=123;      public static int age=22;  }

---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
0 0
原创粉丝点击