黑馬程序員-java-高新技術上《九》

                   ——Java培訓、Android培訓、iOS培訓、.Net培訓、期待與您交流! ——

一:java1.5新特性(1:提高安全性  2:提高效率  3:簡化書寫)

1.靜態導入

   import :導入某個類或,某個包下的所有類。

   import static : 導入某個類中的所有靜態成員或某個靜態成員

    a.導入某個類的所有靜態成員(方法和變量):  import static 包名.類名.*;

    b.導入某個類的某個靜態成員: import static 包名.類名.靜態成員名稱;

2.可變參數(方法的參數)

   爲了增強方法的重載,使得方法可以接收多個(不確定)參數,Java通過隱式的創建一個數組來存儲

   可變參數,在方法內可以以數組形式訪問它。

   注意:可變的參數只能在參數列表的後面。

    用法:add(3);  //只傳入x=3,   add(3,4,5,6); //x=3,後面的賦給數組args.

public static void add(int x,int ...args)
{
       int sum=x;
       for(int e:args)
      {
          sum+=e;
      }
        System.out.println("add:"+sum);
}

3.自動拆裝箱操作

   裝箱:基本數據類型包裝爲對應的包裝類對象
   拆箱:包裝類對象轉換成對應的基本數據類型

//JDK5.0之前:  
        Integer obj1 = Integer.valueOf(1);  
          
        //JDK5.0之後: 
 
        Integer obj2 = 2;    //自動裝箱:將基本數據類型轉換成Integer對象 
        Integer    it=4;
            int     i=it+5;
        Integer   it2=i+4;   
 

 
 
        System.out.println(obj2 + 3);   //自動拆箱:將Integer對象轉換成基本數據類型後相加  
          
        //-128~127的數字包裝成Integer對象後,會緩存到一個對象池中,當要用到的時候會先到池中找  
        //提高效率:因爲這些小整數會經常用到  
        Integer obj3 = 127;  
        Integer obj4 = 127;  
        System.out.println(obj3 == obj4);  
          
        Integer obj5 = 128;  
        Integer obj6 = 128;  
        System.out.println(obj5 == obj6);  
          
        Integer obj7 = Integer.valueOf(1);  
        System.out.println(obj1 == obj7);

運行結果:5
              true

              false

              true

4.增強性for循環

    好處:適合用於遍歷,提高了效率。

    壞處:無法得知變量的下標
   注意: 只能是數組集合類型(實現了Iterator接口)

   用法: for( type 變量名:變量集合名) ,如上

二:枚舉

      定義:枚舉也是一種類,只是比較特別,它將所有的有限個實例對象放在它的內部,你可以通過“枚舉名.枚舉實例”來訪問它的實例對象。 

      適用環境:當你用到某個類,而且它只有有限個實例對象,它的類型不確定很抽象的時候,你可以考慮將它定義成枚舉類,如紅綠燈,季節等。

枚舉類的常用方法:

  (1)  ordinal()方法: 返回枚舉值在枚舉類種的順序。這個順序根據枚舉值聲明的順序而定。

  (2) compareTo()方法: Enum實現了java.lang.Comparable接口,因此可以比較與指定對象的順序。Enum中的compareTo返回的是兩個枚舉值的順序之差。當然,前提是兩個枚舉值必須屬於同一個枚舉類,否則會拋出ClassCastException()異常。

  (3) values()方法: 靜態方法,返回一個包含全部枚舉值的數組。

  (4) toString()方法: 返回枚舉常量的名稱。

  (5) valueOf(Class<T> enumType, String name)方法: 這個方法和toString方法是相對應的,返回帶指定名稱的指定枚舉類型的枚舉常量。

  (6)  equals()方法: 比較兩個枚舉類對象的引用

1.枚舉類

   一個類的實例是有限且固定的,則這個類稱爲枚舉類。比如季節類,只有四個對象(春、夏、秋、冬)。

//創建一個枚舉類的
  /*
  (1)通過private將構造器隱藏起來
  (2)把這個類的所有可能實例都使用private static final修飾的類變量來保存。
  (3)如果有必要,可以提供一些靜態方法。
  */
  public class Demo
  {
      public static void main (String []args)
     {
        System.out.println("spring:"+Season.SPRING.getName());
     }
 }
 class Season 
 {   
     private   String name;
     private   Season (String name)
     {
         this.name=name;
     }
     public static final Season SPRING=new Season ("春天") ;
     public static final Season SUMMER=new Season("夏天");
     public static final Season AUTUMN=new Season ("秋天");
     public static final Season WINTER=new Season ("冬天");
     public   String getName()
     {
        return this.name;
     }
 
 }

2.不可變類
   不可變類:創建該類的實例後,該實例的Field是不可改變的。
   如果要創建自定義的不可變類,需遵循如下規則:

  1.  使用private和final修飾符來修飾該類的Field

  2.  提供帶參數的構造函數,用於根據傳入參數來初始化類裏的Field。

  3.  僅爲該類的Field提供getter方法,不要爲該類的Field提供setter方法。

  4.  如果有必要,重寫Object類的hashCode和equals方法。

3.Enum類(枚舉)

  1.  使用enum關鍵字定義枚舉類。枚舉類一樣可以有自己的Field、方法,可以實現一個或多個接口,也可以有自己的構造器

  2.  使用eunm定義的枚舉類默認繼承了java.lang.Enum類,而不是繼承Object類。

  3.  使用enum定義、非抽象的枚舉類默認會使用final修飾,因此枚舉類不能派送子類。(並不是所有的枚舉類都使用final修飾,如抽象枚舉類)

  4.  枚舉類所有實例必須在枚舉類的第一行顯示列出,否則這個枚舉類永遠不能產生實例。

  5.  所有枚舉類都提供一個values方法,該方法可以方便地遍歷所有枚舉值。

      enum的常用靜態方法:

          枚舉類名.values() ;//以數組的形式返回該枚舉的所有實例

          Enum.valueOf(枚舉類名.class,枚舉實例名); //返回該枚舉類下指定的枚舉實例。

//訪問枚舉類的實例,或方法,以“枚舉類名.實例”,“枚舉類名.方法名”訪問
 //使用enum定義一個簡單的枚舉類
 //使用enum的values()方法,遍歷所有的枚舉
 public class Demo1
 {
     public static void main(String []args) throws Exception
     {
         method(SeasonEnum.SUMMER);
         method2();
     }
     public static void method2()
     { 
         for ( SeasonEnum se: SeasonEnum.values() )
         {
             System.out.println("SeasonEnum:"+se);
         }
     }
     public static void method(SeasonEnum s)
     {
         switch (s)
         {
         default: System.out.println("null"); break;
         case SPRING: System.out.println("spring"); break;
         case SUMMER: System.out.println("summer"); break;
         case AUTUMN: System.out.println("autumn"); break;
         case WINTER: System.out.println("winter"); break;
         
         }
 
     }
 }
  enum SeasonEnum
 {
     SPRING ,SUMMER, AUTUMN ,WINTER ;
 
 }

3.1一個規範化的枚舉類(擁有自己不可變的Field)

  /*
   枚舉類可以定義自己的Field和方法。 
   枚舉類通常應該設計不可變類。其Field值不應該允許改變,這樣會更安全。
   所以枚舉類的Field都應該使用private final修飾。
   枚舉實例名稱一般都是大寫字母
   Enum.valueOf()方法演示
 */
 enum Gender
 {
     MALE("男"),FEMALE("女");
     private Gender(String sex)
     {
         this.sex=sex;
     }
     private final String sex;
     public String getSex()
     {
       return sex;
     }
 }
 public class Demo2
 {
     public static void main (String []args)
     {
         Gender g=Gender.MALE;
         System.out.println("Gender.MALE:"+g.getSex());
         //使用Enum.valueOf()方法訪問枚舉類下的某個實例
         Gender g2=Enum.valueOf(Gender.class,"FEMALE");
         System.out.println("Enum.valueOf(Gender.class,\"FEMALE\"):"+g2.getSex());
     }
 }

3.2枚舉類實現一個或多個接口(且不同枚舉實例有各自的接口實現方法)

//枚舉類實現一個或多個接口(且不同枚舉實例有各自的接口實現方法)
 public class Demo3
 {
     public static void main (String []args)
    {
       Gender.MALE.info();
     }
 }
//以下代碼需要放在GenderInter.java文件中
public interface GenderInter
{
    public void info();

}
 enum Gender implements GenderInter
{
    MALE("男")
    {
        public void info()
        {
         System.out.println("我是男的");
        }
    },FEMALE("女")
    {
        public void info()
        {
         System.out.println("我是女的");
        }
    };
    private Gender(String sex)
    {
        this.sex=sex;
    }
    private final String sex;
    public String getSex()
    {
      return sex;
    }
}

3.3 包含抽象方法的枚舉類

 含有抽象方法的枚舉類,它的每一個枚舉實例必須覆蓋重寫該抽象方法

//注意:含有抽象方法的枚舉類,它的每一個枚舉實例必須覆蓋重寫該抽象方法
 public class EnumAbstractDemo {

    /**
      * @param args
     */
    public static void main(String[] args) {
         // TODO Auto-generated method stub
        System.out.println("plus:5+2="+Operation.PLUS.eval(5, 2));
        System.out.println("minus:5-2="+Operation.MINUS.eval(5, 2));
        System.out.println("times:5*2="+Operation.TIMES.eval(5, 2));
        System.out.println("divide:5/2="+Operation.DIVIDE.eval(5, 2));
     }
 
 }
 enum Operation
 {
     //定義四種加減乘除的枚舉值
     PLUS {
         @Override
         public double eval(double x, double y) {
             // TODO Auto-generated method stub
             return x+y;
         }
     },MINUS {
        @Override
        public double eval(double x, double y) {
             // TODO Auto-generated method stub
             return x-y;
         }
     },TIMES {
         @Override
         public double eval(double x, double y) {
             // TODO Auto-generated method stub
             return x*y;
         }
     },DIVIDE() {
         @Override
         public double eval(double x, double y) {
             // TODO Auto-generated method stub
             return x/y;
         }
     };
     public abstract double eval(double x,double y);
 }

 三:反射

1.反射

   反射庫(Reflection Library)提供一個豐富的工具集,以便編寫能夠動態操作Java代碼的程序。這項功能被

   大量的應用在JavaBeans中,它是Java組件的體系結構。

   能夠分析類能力的程序稱爲反射(Reflection),即可以將一個類(或基本數據類型),類成員當成一個對象來操作

   它是運行時檢測和修改某個對象的結構及其行爲,與內省(introspection)不同。內省是反射的一個子集

   反射:用於運行時檢測和修改某個對象的結構及其行爲。

   內省:用於運行時檢測某個對象的類型及其包含的屬性。

   注意:這裏是指運行時期,即如果編譯時期不可以做的事情,我在運行時期使用反射就可以做了,如向定義了ArrayList <String>的集合裏,運用反射加入int型數據

   內省實例: 對象名  instanceof  類名/接口名;//檢測某個對象是否屬於某個類或接口

   反射實例:Class.forName()方法可以獲取某個類。

2.Class類

   一個Class對象實際上表示的是一個類型,這個類型不一定是一種類,因爲它也可以表示基本數據類型

   它可以將Java裏的所有東西(類,接口,數組,基本數據類型,void)當成一個對象來對它的屬性進行訪問。

3.反射包(java.lang.reflect)下的Constructor類,Field類(成員變量),Method類(成員方法)

總結:

      1,創建Class實例對象的三種方法:

           a,Class<?> c=Class.forName(String name);

           b,Class<?> c=p.getClass();//對象名.getClass()

           c,Class<?> c=Person.Class ;//類名.Class;

      2,獲取構造方法(Constructor),成員變量(Field),成員方法(Method),接口(interface)

          Class類: getDeclaredXxxx();// 獲取本類中的所有Xxxx,不包括繼承父類中xxx

                        getXxxx();//獲取本類中的public權限的Xxxx。

package hq.com.ClassDemo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ClassDemo {

    /**
     * class類的演示
     */
    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        Demo1();
        System.out.println("---------------------");
        Demo2();
        System.out.println("---------------------");
        Demo3();
        System.out.println("---------------------");
        Demo4();
        System.out.println("---------------------");
        Demo5();
        System.out.println("---------------------");
        Demo6();
        System.out.println("---------------------");
        Demo7();
        System.out.println("---------------------");
        Demo8();
    }
    //1.任何所有東西都是Class類的實例對象
    //創建Class實例的三種方法,Class.forName(),類名.class,對象名.getClass().
    public static void Demo1() throws ClassNotFoundException
    {
        Class<?> c1=null;
        Class<?> c2=null;
        Class<?> c3=null;
        //1,Class.forName()方法,推薦
        c1=Class.forName("hq.com.ClassDemo.Person");
        System.out.println("Demo1(寫法1:forName()):類名="+c1.getName());
        //2,類名.class。在java中,每個class都有一個相應的Class對象,當編寫好一個類,
                     // 編譯完成後,在生成的.class文件中,就產生一個class對象
        c2=Person.class;
        System.out.println("Demo1(寫法2:類名.class):類名="+c2.getName());
        //3,object類的getClass()方法
        Person p=new Person();
        c3=p.getClass();
        System.out.println("Demo2(寫法3:getClass()):類名="+c3.getName());
    }
    // 2,Object的getClass()方法,Class的getName(),getPackage().
    // 演示反射機制獲取類的包名和類名
    public static void Demo2() {
        Person p = new Person("hq", 22);
        System.out.println("person的類名:" + p.getClass().getName());
        System.out.println("person的包名:" + p.getClass().getPackage().getName());
    }
   //3,class的newInstance()方法
   //  通過反射,用class來創建類對象(這是反射的意義所在)
    public static void Demo3() throws  Exception
    {
        Class c=Class.forName("hq.com.ClassDemo.Person");
        Person p= (Person) c.newInstance();//要強轉,默認是Object類
        p.setName("hq");
        System.out.println("Demo3(class的newInstance()方法):name="+p.getName());
    }
    //4,class的getConstructors();以數組形式返回該類的所有公共構造方法
    //   java.lang.reflect.Constructor;構造方法類
    public static void Demo4() throws  Exception
    {
        //用構造方法類創建該類的實例對象。
        //注意必須按順序獲取Constructor,即ct[0]在ct[1]之前,不能反過來
        Class   c = null;
        Person p1 = null;
        Person p2 = null;
                c = Class.forName("hq.com.ClassDemo.Person");
        Constructor<?> [] ct=c.getConstructors();
        p1=(Person) ct[0].newInstance();
        p1.setName("hh");
        p2=(Person) ct[1].newInstance("hq",22);
        System.out.println("Demo4(getConstructors()構造方法類創建實例對象):p1:name="+p1.getName());
        System.out.println("Demo4(getConstructors()構造方法類創建實例對象):p2:name="+p2.getName());
    }

    //5,class:  getDeclaredField(String name);獲取該類的成員變量
    //  Field類:操作類對象的成員變量,set,get方法
    public static void Demo5() throws Exception 
    {
       //class的getDeclaredField(String name)方法獲取類中的某個成員變量
       //Field類的set(Object obj,Object value),修改該字段上某個對象對應的值
        Class  c=Class.forName("hq.com.ClassDemo.Person");
        Person p=(Person)c.newInstance();
        Field f=c.getDeclaredField("age");
        f.setAccessible(true);
        f.set(p, 11);
        System.out.println("Demo5(Field的set(對象,值)):person:age="+p.getAge());
        System.out.println("Field.get():"+f.get(p));
        
    }
    //6,獲取該類的父類信息,成員方法,接口,成員變量(字段)
    public static void Demo6() throws  Exception
    {   
        //注意:getDeclaredFields()和getFields()區別是,
        //前者是所有聲明的字段,後者是僅爲public權限的字段
        //注意:兩者獲取的字段均爲該類內部中定義的,不包括繼承父類的字段
        Class<?> c=Class.forName("hq.com.ClassDemo.SuperMan");
        Class<?> superClass=c.getSuperclass();
        System.out.println("Demo6:superman的父類是:"+superClass.getName());
        //獲取類中所有字段
        Field [] fs=c.getDeclaredFields();
        int i=0;
        for(Field f:fs)
        {   
          i++;
         System.out.println("superman的第"+i+"個成員:"+f.getName());
        }
        //獲取類中所有方法
        Method [] ms=c.getDeclaredMethods();
        for(Method m:ms)
        {    
             i++;
             System.out.println("superman的第"+i+"個成員方法:"+m.getName());
         }
        //獲取類實現的接口
        Class<?>[] is=c.getInterfaces();
        for(Class<?> j:is)
        {
             System.out.println("superman的第"+i+"個接口:"+j.getName());
        }
    }
    //7,調用類的方法,Method類的invoke()方法
    public static void Demo7() throws Exception
    {
        Class<?> c=Class.forName("hq.com.ClassDemo.SuperMan");
        //調用類中的無參數方法
        Method  m1=c.getMethod("fly");
        System.out.print("Demo7:superman中的無參數方法fly():");
        m1.invoke(c.newInstance());
        //調用類中的參數方法,先取出該方法,再放入參數(實例,方法參數)
        Method m2=c.getMethod("walk",int.class);
        System.out.print("Demo7:superman中的有參數方法walk():");
        m2.invoke(c.newInstance(),4);
    }
    /** 
     * Demo8: 通過Java反射機制得到類加載器信息 
     *  
     * 在java中有三種類類加載器。[這段資料網上截取] 
 
        1)Bootstrap ClassLoader 此加載器採用c++編寫,一般開發中很少見。 
 
        2)Extension ClassLoader 用來進行擴展類的加載,一般對應的是jre\lib\ext目錄中的類 
 
        3)AppClassLoader 加載classpath指定的類,是最常用的加載器。同時也是java中默認的加載器。   
     */ 
    public static void Demo8() throws ClassNotFoundException  
    {  
        Class<?> class1 = null;  
        class1 = Class.forName("hq.com.ClassDemo.SuperMan");  
        String nameString = class1.getClassLoader().getClass().getName();  
          
        System.out.println("Demo8: 類加載器類名: " + nameString);  
    }  
}
class SuperMan extends Person implements ActionInterface 
{
    
    private boolean BlueBriefs;
    public boolean isBuleBriefs()
    {
        return this.BlueBriefs;
    }
    public void setBuleBriefs(boolean BlueBriefs)
    {
        this.BlueBriefs=BlueBriefs;
    }
    public void fly()
    {
        System.out.println("超人會飛哦~~");
    }
    @Override
    public void walk(int m) {
        // TODO Auto-generated method stub
        System.out.println("超人也會走耶~~走了"+m+"米後走不動了");
    }
    
}
interface ActionInterface
{
    public void walk(int m);
}
class Person {
    private int age;
    private String name;

    public Person() {

    }

    public Person(String name, int age) {
        this.age = age;
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return this.age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
}

 總結:

數組的反射:

1.具有相同維數和元素類型的數組屬於同一個類型,即具有相同的Class實例對象。

2.代表數組的Class實例對象的getSuperclass()方法返回的父類爲Object類對應的Class.

3.基本類型的一維數組可以被當作Object類型使用,不能當作Object[]類型使用;非基本類型的一維數組,既可以當做Object類型使用,又可以當做Object[]類型使用。

4.Arrays.asList()方法處理int[]和String[]時的差異。

   Arrays工具類用於完成對數組的反射操作。

 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章