一般而言,說到動態言,都是指在程序運行時允許改變程序結構或者變量類型,從這個觀點看,JAVA和C++一樣,都不是動態語言。
但JAVA它卻有著一個非常突出的動態相關機制:反射。通過反射,Java可以於運行時加載、探知和使用編譯期間完全求和的類、生成其對象實體,調用其方法或者對屬性設值。所以Java算是一個半動態的語言吧。
反射的概念:
在Java中的反射機制是指在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;
對於任意一個對象,都能夠調用它的任意一個方法;
這種動態獲取信息以及動態調用對象方法的功能稱為Java語言的反射機制
在Java程序中許多對象在運行時都會出現兩種類型:編譯時類型和運行時類型
編譯時的類型由聲明該對象時使用的類型決定,運行時的類型由實際賦給對象的類型決定
如:
Person p =new Student();
編譯時類型為Person,而運行時為Student
除此之外,程序在運行時還可能接收到外部傳入的一個對象,該對象的編譯時類型為Object,但程序又需要調用該對象運行時類型的方法。為了這些問題程序需要在運行時發現對象和類的真實信息。然而,如果編譯時根本無法預知該對象和類可能屬於哪些類,程序只依靠運行時信息來發現該對象和類的真實信息,此時就必須使用反射
反射API用來生成在當前JAVA虛擬機中的類、接口或者對象的信息。
Person類
package com.pb.Reflect.classinfo;
public class Person {
private String name;
private String gender;
private int age;
private Person() {
//
}
public Person(String name, String gender, int age) {
super();
this.name = name;
this.gender = gender;
this.age = age;
}
//getter、和setter方法
private String getName() {
return name;
}
private void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return "姓名:"+name+"年齡: "+age;
}
}
使用反射:
package com.pb.Reflect.classinfo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.swing.JOptionPane;
/*
* 通過用戶輸入類的全路徑,來獲取該類的成員方法和屬性
* Declared獲取全部不管是私有和公有
* 1.獲取訪問類的Class對象
* 2.調用Class對象的方法返回訪問類的方法和屬性信息
*/
public class ReflectDemo {
/*
* 構造方法
*/
public ReflectDemo(){
//用戶輸入類的全路徑徑
//使用String組件
String classpsth=JOptionPane.showInputDialog(null,"輸入類的全路徑");
//使用Class.forName方法根據輸入的類的全路徑 返回該類的Class對象
try {
Class cla = Class.forName(classpsth);
//利用Class對象的cla的自審,返回方法對象集合
Method [] method=cla.getDeclaredMethods(); //返回所有的方法
System.out.println("========獲取方法信息============");
for (Method meth : method) {
//遍歷method數組,並輸出方法信息
System.out.println(meth.toString());
}
System.out.println("========獲取出方法信息結束============");
//獲取屬性利用Class對象的cla的自審,返回成員屬性對象集合
Field [] field=cla.getDeclaredFields();
System.out.println("========獲取成員屬性信息============");
for (Field f : field) {
System.out.println(f.toString());
}
System.out.println("========獲取成員屬性信息結束============");
//獲取屬性利用Class對象的cla的自審,返回構造方法集合
Constructor [] constructor=cla.getDeclaredConstructors();
System.out.println("========獲取成員構造方法信息============");
for (Constructor constru : constructor) {
System.out.println(constru.toString());
}
System.out.println("========獲取成員構造方法信息結束============");
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("路徑輸入錯誤!");
}
}
}
package com.pb.Reflect.classinfo;
public class TestReflection {
public static void main(String[] args) {
ReflectDemo rd=new ReflectDemo();
}
}
輸入com.pb.Reflect.classinfo.Person
結果:
========獲取方法信息============ public java.lang.String com.pb.Reflect.classinfo.Person.getGender() public void com.pb.Reflect.classinfo.Person.setGender(java.lang.String) public int com.pb.Reflect.classinfo.Person.getAge() public void com.pb.Reflect.classinfo.Person.setAge(int) public java.lang.String com.pb.Reflect.classinfo.Person.toString() private java.lang.String com.pb.Reflect.classinfo.Person.getName() private void com.pb.Reflect.classinfo.Person.setName(java.lang.String) ========獲取出方法信息結束============ ========獲取成員屬性信息============ private java.lang.String com.pb.Reflect.classinfo.Person.name private java.lang.String com.pb.Reflect.classinfo.Person.gender private int com.pb.Reflect.classinfo.Person.age ========獲取成員屬性信息結束============ ========獲取構造方法信息============ private com.pb.Reflect.classinfo.Person() public com.pb.Reflect.classinfo.Person(java.lang.String,java.lang.String,int) ========獲取構造方法信息結束============
Java.lang.reflect
Person p = new Person(); Class cla=p.getClass();
Class cls=Person.class;
Class cla=Class.forName(“類的全路徑”);
Person類,因為要聲明對象所以將構造方法public
package com.pb.Reflect.classinfo;
public class Person {
private String name;
private String gender;
private int age;
public Person() {
//
}
public Person(String name, String gender, int age) {
super();
this.name = name;
this.gender = gender;
this.age = age;
}
//getter、和setter方法
private String getName() {
return name;
}
private void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return "姓名:"+name+"年齡: "+age;
}
}
使用反射:
package com.pb.Reflect.classinfo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.swing.JOptionPane;
/*
* 通過用戶輸入類的全路徑,來獲取該類的成員方法和屬性
* Declared獲取全部不管是私有和公有
* 1.獲取訪問類的Class對象
* 2.調用Class對象的方法返回訪問類的方法和屬性信息
*/
public ReflectDemo(Person p){
Class cla=p.getClass();
//利用Class對象的cla的自審,返回方法對象集合
Method [] method=cla.getDeclaredMethods(); //返回所有的方法
System.out.println("========獲取方法信息============");
for (Method meth : method) {
//遍歷method數組,並輸出方法信息
System.out.println(meth.toString());
}
System.out.println("========獲取出方法信息結束============");
//獲取屬性利用Class對象的cla的自審,返回成員屬性對象集合
Field [] field=cla.getDeclaredFields();
System.out.println("========獲取成員屬性信息============");
for (Field f : field) {
System.out.println(f.toString());
}
System.out.println("========獲取成員屬性信息結束============");
//獲取屬性利用Class對象的cla的自審,返回構造方法集合
Constructor [] constructor=cla.getDeclaredConstructors();
System.out.println("========獲取成員構造方法信息============");
for (Constructor constru : constructor) {
System.out.println(constru.toString());
}
System.out.println("========獲取成員構造方法信息結束============");
}
}
測試類
package com.pb.Reflect.classinfo;
public class TestReflection {
public static void main(String[] args) {
Person p=new Person();
ReflectDemo rd=new ReflectDemo(p);
}
}
========獲取方法信息============ public java.lang.String com.pb.Reflect.classinfo.Person.getGender() public void com.pb.Reflect.classinfo.Person.setGender(java.lang.String) public int com.pb.Reflect.classinfo.Person.getAge() public void com.pb.Reflect.classinfo.Person.setAge(int) public java.lang.String com.pb.Reflect.classinfo.Person.toString() private java.lang.String com.pb.Reflect.classinfo.Person.getName() private void com.pb.Reflect.classinfo.Person.setName(java.lang.String) ========獲取出方法信息結束============ ========獲取成員屬性信息============ private java.lang.String com.pb.Reflect.classinfo.Person.name private java.lang.String com.pb.Reflect.classinfo.Person.gender private int com.pb.Reflect.classinfo.Person.age ========獲取成員屬性信息結束============ ========獲取成員構造方法信息============ public com.pb.Reflect.classinfo.Person() public com.pb.Reflect.classinfo.Person(java.lang.String,java.lang.String,int) ========獲取成員構造方法信息結束============
Person類同上
測試類:
package com.pb.Reflect.classinfo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class TestReflection {
public static void main(String[] args) {
/*第二種方法
Person p=new Person();
ReflectDemo rd=new ReflectDemo(p);
*/
/*
* 第三種方式.class屬性
*/
Class cla=Person.class;
//利用Class對象的cla的自審,返回方法對象集合
Method [] method=cla.getDeclaredMethods(); //返回所有的方法
System.out.println("========獲取方法信息============");
for (Method meth : method) {
//遍歷method數組,並輸出方法信息
System.out.println(meth.toString());
}
System.out.println("========獲取出方法信息結束============");
//獲取屬性利用Class對象的cla的自審,返回成員屬性對象集合
Field [] field=cla.getDeclaredFields();
System.out.println("========獲取成員屬性信息============");
for (Field f : field) {
System.out.println(f.toString());
}
System.out.println("========獲取成員屬性信息結束============");
//獲取屬性利用Class對象的cla的自審,返回構造方法集合
Constructor [] constructor=cla.getDeclaredConstructors();
System.out.println("========獲取成員構造方法信息============");
for (Constructor constru : constructor) {
System.out.println(constru.toString());
}
System.out.println("========獲取成員構造方法信息結束============");
}
}
結果:
同上
========獲取方法信息============ public java.lang.String com.pb.Reflect.classinfo.Person.getGender() public void com.pb.Reflect.classinfo.Person.setGender(java.lang.String) public int com.pb.Reflect.classinfo.Person.getAge() public void com.pb.Reflect.classinfo.Person.setAge(int) public java.lang.String com.pb.Reflect.classinfo.Person.toString() private java.lang.String com.pb.Reflect.classinfo.Person.getName() private void com.pb.Reflect.classinfo.Person.setName(java.lang.String) ========獲取出方法信息結束============ ========獲取成員屬性信息============ private java.lang.String com.pb.Reflect.classinfo.Person.name private java.lang.String com.pb.Reflect.classinfo.Person.gender private int com.pb.Reflect.classinfo.Person.age ========獲取成員屬性信息結束============ ========獲取成員構造方法信息============ public com.pb.Reflect.classinfo.Person() public com.pb.Reflect.classinfo.Person(java.lang.String,java.lang.String,int) ========獲取成員構造方法信息結束============