JAVA反射機制是在運行狀態中,對於任意一個類,都可以獲取這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意一個方法和屬性;這種動態獲取類信息以及動態調用對象內容就稱爲java語言的反射機制。【翻譯於 官方文檔】html
從結果來講沒有區別。java
new:靜態編譯,只能用於編譯期就能肯定的類型,並且須要import相應的包。數組
反射:動態編譯,在運行時能夠肯定類型並建立其對象,可以實現一些更爲動態的效果。bash
咱們知道,要使用一個類,就要先把它加載到虛擬機中,生成一個Class對象。這個class對象就保存了這個類的一切信息。 反射機制的實現,就是獲取這個Class對象,經過Class對象去訪問類、對象的元數據以及運行時的數據。有三種方法得到類的Class對象:spa
在面向對象的世界裏,萬物皆對象。類是對象,類是java.lang.Class類的實例對象。另外class類只有java虛擬機才能new出來,任何一個類都是Class 類的實例對象,這實例對象有三種表達方式:翻譯
public class Person {
}
複製代碼
public class PersonClassTest {
public static void main(String[] args) {
try {
Person p = new Person();
//方式1
Class p1 = Person.class;
//方式2
Class p2 = p.getClass();
//方式3
Class p3 = Class.forName("com.java.xiaoxin.Person");
//能夠經過類的類型建立該類的實例對象
Person person = (Person) p1.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
}
複製代碼
反射首先獲取Class對象;而後獲取Method類和Field類;最後經過Method和Field類進行具體的方法調用或屬性訪問。code
對象名.getClass().getName();
複製代碼
public class PersonClassTest {
public static void main(String[] args) {
String name = Person.class.getName();
System.out.println(name);//com.java.xiaoxin.Person
}
}
複製代碼
Class<?> clazz = Class.forName(當前類);
Class<?> parentClass = clazz.getSuperclass();
parentClass.getName();//得到父類名
複製代碼
public class PersonClassTest {
public static void main(String[] args) {
try {
Class<?> clazz = Class.forName("com.java.xiaoxin.Person");
Class<?> parentClass = clazz.getSuperclass();
parentClass.getName();
System.out.println(parentClass.getName());//java.lang.Object
}catch (Exception e){
e.printStackTrace();
}
}
}
複製代碼
1:反射建立class對象
2:Classname 對象=classname.newInstance(參數);
複製代碼
public class PersonClassTest {
public static void main(String[] args) {
try {
Class clazz = Class.forName("com.java.xiaoxin.Person");
Person person = (Person) clazz.newInstance();
}catch (Exception e){
e.printStackTrace();
}
}
}
複製代碼
//建立class對象
Class<?> clazz = Class.forName(ClassName);
// 返回聲明的全部方法,包括公共、保護、默認(包)訪問和私有方法,但不包括繼承的方法。
Method[] method1 = clazz.getDeclaredMethods();
//返回可被訪問的公共方法
Method[] method2 = clazz.getMethods();
複製代碼
public class PersonClassTest {
public static void main(String[] args) {
try {
Class clazz = Class.forName("com.java.xiaoxin.Person");
/** * 一個成員方法就是一個method對象 * getMethod()全部的 public方法,包括父類繼承的 public * getDeclaredMethods()獲取該類全部的方法,包括private ,但不包括繼承的方法。 */
Method[] methods = clazz.getMethods();//獲取方法
//獲取因此的方法,包括private ,c.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
//獲得方法的返回類型
Class returnType = methods[i].getReturnType();
System.out.print(returnType.getName());
//獲得方法名:
System.out.print(methods[i].getName() + "(");
Class[] parameterTypes = methods[i].getParameterTypes();
for (Class class1 : parameterTypes) {
System.out.print(class1.getName() + ",");
}
System.out.println(")");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
複製代碼
輸出:htm
voidwait()
voidwait(long,int,)
voidwait(long,)
booleanequals(java.lang.Object,)
java.lang.StringtoString()
inthashCode()
java.lang.ClassgetClass()
voidnotify()
voidnotifyAll()
複製代碼
Class<?> clazz = Class.forName(classname);
// 取得本類已聲明的全部字段,包括私有的、保護的
Field[] field = clazz.getDeclaredFields();
// 取得本類中可訪問的全部公共字段
Field[] filed1 = clazz.getFields();
複製代碼
public class Person {
private String name;
public int age;
}
複製代碼
public class PersonClassTest {
public static void main(String[] args) {
try {
Class clazz = Class.forName("com.java.xiaoxin.Person");
Field[] field = clazz.getDeclaredFields();
Field[] filed1 = clazz.getFields();
for(Field f:field){
//獲取成員變量的類型
Class filedType=f.getType();
System.out.println(filedType.getName()+"-->"+f.getName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
複製代碼
輸出:對象
java.lang.String-->name
int-->age
複製代碼
獲取一個方法:須要獲取方法的名稱和方法的參數才能決定一個方法。blog
方法的反射操做:
method.invoke(對象,參數列表);
複製代碼
public class Person {
private String name;
public int age;
public void say(String name,int age){
System.out.print(name+"今年"+age+"歲");
}
}
複製代碼
public class PersonClassTest {
public static void main(String[] args) {
try {
Person person=new Person();
Class clazz=person.getClass();
Method method=clazz.getMethod("say",new Class[]{String.class,int.class});
//也能夠 Method method=c.getMethod("add",String.class,int.class);
//方法的反射操做
method.invoke(person,"小新",18);
} catch (Exception e) {
e.printStackTrace();
}
}
}
複製代碼
輸出:
小新今年18歲
複製代碼