類的反射_reflex
JAVA反射機制
JAVA反射機制是在執行狀態中,對於任意一個實體類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意方法和屬性;這種動態獲取資訊以及動態呼叫物件方法的功能稱為java語言的反射機制。
JAVA反射(放射)機制:“程式執行時,允許改變程式結構或變數型別,這種語言稱為ofollow,noindex">動態語言 ”。從這個觀點看,Perl,Python,Ruby是動態語言,C++,Java,C#不是動態語言。但是JAVA有著一個非常突出的動態相關機制:Reflection,用在Java身上指的是我們可以於執行時載入、探知、使用編譯期間完全未知的classes。換句話說,Java程式可以載入一個執行時才得知名稱的class,獲悉其完整構造(但不包括methods定義),並生成其物件實體、或對其fields設值、或喚起其methods。
功能
Java反射機制主要提供了以下功能: 在執行時判斷任意一個物件所屬的類;在執行時構造任意一個類的物件;在執行時判斷任意一個類所具有的成員變數 和方法;在執行時呼叫任意一個物件的方法;生成動態代理。
程式碼演示
package com.svse.reflex;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Properties;
import org.junit.Test;
/***
* 類的反射
* @author Administrator
* java反射機制提供的功能
* 在執行時:
* <1>判斷任意一個物件所屬的類
* <2>構造任意一個類的物件
* <3>判斷任意一個類所具有的成員變數和方法
* <4>呼叫任意一個物件的成員變數和方法
* <5>生成動態代理
*/
public class ClassReflex {
//關於類的載入器classLoader
@Test
public void test5() throws ClassNotFoundException, IOException{
ClassLoader classLoader=ClassLoader.getSystemClassLoader();
System.out.println(classLoader);
ClassLoader classLoader1=classLoader.getParent();
System.out.println(classLoader1);
ClassLoader classLoader2=classLoader1.getParent();
System.out.println(classLoader2);
Class clazz=Person.class;
ClassLoader classLoader3=clazz.getClassLoader();
System.out.println(classLoader3);
String forName="java.lang.String";
Class clazz2=Class.forName(forName);
ClassLoader classLoader4=clazz2.getClassLoader();
System.out.println(classLoader4);
ClassLoader classLoader5=this.getClass().getClassLoader();
InputStream is=classLoader5.getResourceAsStream("com\\svse\\reflex\\db.properties");//讀取properties檔案資訊
Properties properties=new Properties();
properties.load(is);
String name=properties.getProperty("name");
String password=properties.getProperty("password");
System.out.println(name+" : "+password);
}
/***
*獲取class例項的三種方式
* @throws ClassNotFoundException
*/
@Test
public void test4() throws ClassNotFoundException{
//1:呼叫執行時類本身的class屬性
Class clazz=Person.class;
System.out.println(clazz.getName());
Class clazz2=String.class;
System.out.println(clazz2.getName());
//2:通過執行時類的物件獲取
Person p=new Person();
Class clazz3=p.getClass();
System.out.println(clazz3.getName());
//3:通過class的靜態方法獲取 (體會一下反射的動態性)
String forName="com.svse.reflex.Person";
Class clazz4=Class.forName(forName);
System.out.println(clazz.getName());
//4:瞭解類的載入器classLoader
ClassLoader classLoader=this.getClass().getClassLoader();
Class clazz5=classLoader.loadClass(forName);
System.out.println(clazz5.getName());
System.out.println(clazz==clazz2);
System.out.println(clazz==clazz3);
System.out.println(clazz==clazz4);
System.out.println(clazz==clazz5);
}
/**
* java.lang.Class 是反射的源頭
* 通過執行時類的getClass()方法建立例項
*/
@Test
public void test3(){
Person p=new Person();
Class clazz=p.getClass();//通過執行時類的物件,呼叫其getClass()方法,返回其執行時類
System.out.println(clazz);
}
//有了反射之後,可以通過反射建立一個類的物件,並呼叫其中的屬性和方法
@Test
public void test2() throws Exception{
Class clazz=Person.class;
//1建立clazz對應的執行時類person的物件
Person p=(Person) clazz.newInstance();
System.out.println(p);
//2 通過反射呼叫類的屬性
Field f1=clazz.getField("name");
f1.set(p, "王小米");
System.out.println(p);
//Field f2=clazz.getField("age");
Field f2=clazz.getDeclaredField("age");//如果屬性設定為private
f2.setAccessible(true);//必須設定允許訪問為true,否則就獲取不到私有屬性的值
f2.set(p, 26);
System.out.println(p);
//3 通過反射呼叫類的方法
Method m1=clazz.getMethod("show");
m1.invoke(p);
Method m2=clazz.getMethod("display",String.class);
m2.invoke(p,"china");
//4
}
//在有反射前,傳統的方法,如何建立一個類的物件,並呼叫其中的屬性和方法
@Test
public void test1(){
Person p=newPerson();
p.setAge(25);
p.setName("張三");
System.out.println(p);
p.show();
p.display("china");
}
}
db.properties檔案
name=zhangsan
password=123456
Person.java檔案
package com.svse.reflex;
public class Person {
public Stringname;
private int age;
public Person() {
super();
}
public Person(String name) {
super();
this.name = name;
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public void add(String name){
System.out.println("公有的---"+name);
}
private void find(String name){
System.out.println("私有的---"+name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void show(){
System.out.println("我是一個man");
}
public void display(String nation){
System.out.println("我的國籍是:"+nation);
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}