——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是不可改變的。
如果要創建自定義的不可變類,需遵循如下規則:
使用private和final修飾符來修飾該類的Field。
提供帶參數的構造函數,用於根據傳入參數來初始化類裏的Field。
僅爲該類的Field提供getter方法,不要爲該類的Field提供setter方法。
如果有必要,重寫Object類的hashCode和equals方法。
3.Enum類(枚舉)
使用enum關鍵字定義枚舉類。枚舉類一樣可以有自己的Field、方法,可以實現一個或多個接口,也可以有自己的構造器。
使用eunm定義的枚舉類默認繼承了java.lang.Enum類,而不是繼承Object類。
使用enum定義、非抽象的枚舉類默認會使用final修飾,因此枚舉類不能派送子類。(並不是所有的枚舉類都使用final修飾,如抽象枚舉類)
枚舉類所有實例必須在枚舉類的第一行顯示列出,否則這個枚舉類永遠不能產生實例。
所有枚舉類都提供一個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工具類用於完成對數組的反射操作。