java 學習筆記7-反射、內部類

反射:

反射:在運行時動態分析或使用一個類進行工作。

java.lang.Class類:描述類信息的類。

類對象:描述一個類信息的對象,當虛擬機加載類的時候,就會創建這個類的類對象並加載該對象,Class是類對象的類型。

獲得類對象的方式:

用" 類名.class "獲得這個類的類對象。

用類的對象掉用getClass(),如object.getClass()得到這個對象的類型的類對象。

可以使用Class.forName(類名),也可以得到這個類的類對象,(注意,這裏寫的類名必須是全限定名(全名),是包名加類名,XXX.XXX.XXXX)。

基本類型也有類對象,用" 封裝類.TYPE "可以獲得對應的基本類型的類對象。


java.lang.reflect包下的三個重要類:

Field屬性類:用來描述屬性的信息。

Method方法類:方法的信息的描述。

Constructor構造方法類:用來描述構造方法的信息。


Class類中的常用方法:

newInstance()

創建此 Class 對象所表示的類的一個新實例(調用無參構造創建的對象)。

getDeclaredMethods()

獲得的是一個Method方法類對象的數組,獲得本類(不包括父類)聲明的所有(包括private的)方法對象。

getMethods()     //推薦使用

獲得的是一個Method方法類對象的數組,獲得所有(父類的也包括)publice的方法對象。

getDeclaredConstructors()

獲得的是一個Constructor構造方法類對象的數組,獲得這個類聲明的所有構造方法對象。

getConstructors()    //推薦使用

獲得的是一個Constructor構造方法類對象的數組,獲得所有publice的構造方法對象。

getDeclaredFields()    //推薦使用

獲得的是一個Field屬性類對象的數組,獲得本類聲明的所有屬性的屬性對象。

getFields()

獲得的是一個Field屬性類對象的數組,獲得所有publice的屬性對象。

使用反射構造一個類的對象的步驟:

a. 獲得類對象

b. 獲得構造方法對象

c. 獲得對象,用構造方法對象調用構造方法,如果使用無參構造方法,可以跳過第二步,直接使用" 類對象.newInstance() "方法來獲得這個類的對象

d. 獲得方法對象

e. 用方法對象調用方法(用這個類的對象作爲第一參數)

如下面的例子:

反射機制的實現類:

package day07.reflect;

import java.lang.reflect.Field;

import java.lang.reflect.Method;

import java.util.HashMap;

import java.util.Map;

import java.util.Set;

public class TestReflect {

public static Object get(String className , Map<String,Object> map) throws Exception{

Class c = Class.forName(className);                  //獲得類對象

Object o = c.newInstance();                   //獲得對象

Set<String> set = map.keySet();

for(String str : set){

String s = "set" + str.substring(0,1).toUpperCase()+str.substring(1);

Field f = c.getDeclaredField(str);

Method m = c.getMethod(s, f.getType());        //獲得方法對象

m.invoke(o, map.get(str));                       //用方法對象調用方法

}

return o;

}

public static void main(String[] args) throws Exception {

Map m = new HashMap();

m.put("name", "zhang");

m.put("age", 22);

Object o = get("day07.reflect.Student",m);

Student s = (Student) o;

System.out.println(s.getName() + "   " + s.getAge());

Map m1 = new HashMap();

m1.put("name", "li");

m1.put("gender", "男");

Object o1 = get("day07.reflect.Teacher",m1);

Teacher t = (Teacher) o1;

System.out.println(t.getName() + "    " + t.getGender());

}

}

學生類:

package day07.reflect;

public class Student {

private String name;

private int age;

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

教師類:

package day07.reflect;

public class Teacher {

private String name;

private String gender;

public String getGender() {

return gender;

}

public void setGender(String gender) {

this.gender = gender;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

}

內部類:

定義:

定義在另外一個類中的類,就是內部類。

編譯後生成的兩個獨立的類:Outer.class 和Outer$Inner.class。

內部類的分類:

靜態內部類:靜態內部類定義在類中,任何方法外,用static修飾

靜態內部類只能訪問外部類的靜態成員。

在外部類的外部,要創建一個靜態內部類對象不需要外部類對象:

Outer.Inner in = new Outer.Inner();

在本類內部生成內部類對象的方式:

Inner in = new Inner();

成員內部類:作爲外部類的一個成員存在,與外部類的屬性、方法並列

在內部類中可以直接訪問外部類的私有屬性。

內部類和外部類的實例變量允許命名衝突。

在內部類中訪問實例變量:this.屬性

在內部類訪問外部類的實例變量:外部類名.this.屬性

在外部類的外部,要創建一個成員內部類對象,要首先建立一個外部類對象,然後再創建一個成員內部類對象。

Outer out = new Outer();

Outer.Inner in = out.new Inner();

在本類內部生成內部類對象的方式:

在靜態方法中:Inner in = new Outer().new Inner();

在非靜態方法中:Inner in = this.new Inner();

成員內部類不可以有靜態成員,這是因爲靜態屬性是在加載類的時候創建,這個時候內部類還沒有被創建。

局部內部類:在外部類的方法中定義的內部類

與局部變量類似,在局部內部類前不可以加修飾符public和private,其作用域爲定義它的代碼塊。

局部內部類不僅可以訪問外部類的實例變量,還可以訪問外部類的局部變量,但要求外部類的局部變量必須爲final的。

配合接口使用,來做到強制弱耦合。

在外部類的外部不可創建局部內部類對象,只能在局部內部類所在的方法中創建:

Inner in = new Inner();

匿名內部類:一種特殊的局部內部類

沒有名字,也沒有class、extends、implements關鍵字

用一種隱含的方式實現一個接口或繼承一個類,並且只能創建一次實例。

實現方式:在某個語句中,new 父類/父接口名字(){ 類體中實現方法 }

例如:

TreesSet ts = new TreeSet(new Comparator(){

public int compare(Object o1, Object o2){

return 0;

}

});

匿名內部類屬於局部內部類,那麼局部內部類的所有限制都對其生效。

匿名內部類是唯一一種無構造方法的類,因爲構造器的名字必須合類名相同,而匿名內部類沒有類名。


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