Java反射機制研究
以前聽同時說反射很強大,看了一些相關文章今天把反射總結一下。
說明:反射主要用於開發框架,即製作框架;
一、獲得Class物件
Class<?> c = Class.forName("classname"); 丟擲ClassNotFoundException
二、獲得實現介面
Class<?> inters[] = c.getInterfaces();
for(int i=0;i<inters.length;i++){
System.out.print(inters[i].getName()+" "); //getName()方法為取得介面名稱;
}
三、獲得父類
Class<?> superClass = c.getSuperclass(); //獲得父類
String name = superClass.getName(); //獲得父類名稱
四、取得構造方法
Constructor cons[] = c.getConstructors(); //獲得公開的構造方法
Constructor dcons[] = c.getDeclaredConstructors(); //獲得全部構造方法
String modifier = Modifier.toString(cons[i].getModifiers()); //獲得訪問許可權
String name = cons[i].getName(); //獲得構造方法名稱
Class<?> params[] = cons[i].getParameterTypes(); //獲得引數型別物件
五、獲得Method
Method ms[] = c.getMethods(); //返回公共的全部方法,包括繼承方法
Method dms[] = c.getDeclaredMethods(); //返回本類全部方法,不包括繼承的方法
Class<?> rt = ms[i].getReturnType();
Class<?>params[] = ms[i].getParameterTypes();
String name = ms[i].getName();
String modifier = Modifier.toString(ms[i].getModifiers());
Class<?>ex[] = ms[i].getExceptionTypes(); //獲得異常
String name = ex[i].getName(); //獲得異常名稱
六、獲得Field
Field fs[] = c.getFields(); //獲得公共屬性,包括繼承屬性
Field dfs[] = c.getDeclaredFields(); // 獲得本類全部屬性
Class<?> type = fs[i].getType(); //獲得屬性的型別物件
String name = fs[i].getName(); //獲得屬性的名稱
String modifier = Modifier.toString(fs[i].getModifiers());
七、通過反射建立一個物件
(1)
Class<?> c = Class.forName("Person");
Person p = (Person)c.newInstance();
(2)
Constructor con = c1.getConstructor(Class....param);
Object obj = con.newInstance(Object obj); //根據建構函式建立一個例項
八、Constructor建立物件
Class c = Class.forName("Person");
Constructor<?> cons[] = c.getConstructors();
Person p = (Person)cons[0].newInstance("xiazdong",15);
注:如果呼叫的建構函式為私有,則需要c.setAccessible(true);
九、呼叫特定方法
Method m = c1.getMethod("funcname",Class<?>...c); //funcname表示呼叫方法的名稱,c表示引數的Class物件
例如:Method m = c1.getMethod("fun",String.class,int.class); 表示呼叫fun(String,int);函式
Object obj = m.invoke(c1.newInstance(),"xiazdong",20); //如果有返回值,則invoke函式返回;
注:如果是呼叫靜態的方法,則不需要設定物件;
Object obj = m.invoke(null,"xiazdong");
注:如果引數中有陣列,比如 public static void main(String[]args);
則
Method m = c1.getMethod("main",String[].class);
m.invoke(null,(Object)new String[]{"aa","bb"});是對的;
m.invoke(null,new String[]{"aa","bb"}); 會呼叫 main(String,String);函式;
十、呼叫特定屬性
Field f = c1.getDeclaredField("name"); //返回name屬性
f.setAccessible(true); //私有屬性可見
String name = (String)f.get(Object obj); //返回obj物件的name屬性的值
f.set(Object obj,String n); //設定obj物件的name屬性為n值;
十一、運算元組
int tmp[] = {1,2,3};
Class<?> c = tmp.getClass().getComponentType();
Array.getLength(tmp); //tmp陣列的長度
c.getName(); //獲得陣列型別名稱
Array.get(Object obj,int index); //獲得obj陣列的index索引的數值
Array.set(Object obj,int index,VALUE); //設定obj陣列的index索引的數值為value;
Object obj = Array.newInstance(c,length); //c為陣列的型別,length為陣列的長度;obj為返回的陣列物件;
示例:
import java.lang.reflect.*;
public class GetMethodDemo01{
public static void main(String args[])throws Exception{
Class<?> c1 = Class.forName("Person");
Method m = c1.getMethod("sayHello");
m.invoke(c1.newInstance());
Method m2 = c1.getMethod("sayHello2",String.class,int.class);
String str = (String)m2.invoke(c1.newInstance(),"xiazdong",123);
System.out.println(str);
Field nameField = c1.getDeclaredField("name");
Field ageField = c1.getDeclaredField("age");
nameField.setAccessible(true);
ageField.setAccessible(true);
Person obj = (Person)c1.newInstance();
obj.setName("xzdong");
obj.setAge(12);
System.out.println(nameField.get(obj));
System.out.println(ageField.get(obj));
Method setName = c1.getMethod("setName",String.class);
setName.invoke(obj,"changed");
Method getName = c1.getMethod("getName");
System.out.println(getName.invoke(obj));
int tmp[] = {1,2,3};
Class<?> c3 = tmp.getClass().getComponentType();
System.out.println(c3.getName());
System.out.println("第一個數:"+Array.get(tmp,0));
Array.set(tmp,0,5);
System.out.println("第一個數:"+Array.get(tmp,0));
Object arr = Array.newInstance(c3,5);
System.arraycopy(tmp,0,arr,0,Array.getLength(tmp));
System.out.println(Array.get(arr,2));
System.out.println(Array.get(arr,3));
}
}
import java.lang.reflect.*;
interface China{
public static final String NAME = "CHINA";
public int AGE = 60;
public void sayHello();
public String sayHello2(String name,int age);
}
class Person implements China{
private String name;
private int age;
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 sayHello(){
System.out.println(NAME+" "+AGE);
}
public String sayHello2(String name,int age){
return name+" "+age;
}
}
十一、工廠設計模式
1.最簡單的工廠設計模式
場景:有一個Fruit介面,Apple類和Orange類都實現了Fruit介面,Factory用來生產水果;
import java.io.*;
import java.util.*;
interface Fruit{
public void eat();
}
class Apple implements Fruit{
public void eat(){
System.out.println("吃蘋果");
}
}
class Orange implements Fruit{
public void eat(){
System.out.println("吃橘子");
}
}
class Factory{
public static Fruit getInstance(String name)throws Exception{
Fruit f = null;
if("apple".equals(name)){
f = new Apple();
}
else if("orange".equals(name)){
f = new Orange();
}
if(f!=null){
return f;
}
else return null;
}
}
public class FactoryDemo01{
public static void main(String args[])throws Exception{
Fruit f = Factory.getInstance("apple");
f.eat();
}
}
2.通過反射實現
上面的例子有一個壞處,就是在Factory的getInstance程式碼會隨著水果數量增加而增加,比如如果增加了一個banana類,則需要新增
if(name.equals("banana")){...}
這樣非常不方便,因此反射就是一個很好的解決方法:
import java.io.*;
import java.util.*;
interface Fruit{
public void eat();
}
class Apple implements Fruit{
public void eat(){
System.out.println("吃蘋果");
}
}
class Orange implements Fruit{
public void eat(){
System.out.println("吃橘子");
}
}
class Factory{
public static Fruit getInstance(String name)throws Exception{
Fruit f = null
Fruit f = (Fruit)Class.forName(name).newInstance();
if(f!=null){
return f;
}
else return null;
}
}
public class FactoryDemo01{
public static void main(String args[])throws Exception{
Fruit f = Factory.getInstance("Apple");
f.eat();
}
}
3.增加靈活性:配置檔案但是還有一個缺點,就是如果Apple類等有包名,則如果要訪問此類,必須新增包名+類名稱才可以。比如Apple類的最上方:package org;則必須通過org.Apple才可以訪問Apple類。因此通過Properties檔案可以解決這個問題;
import java.io.*;
import java.util.*;
interface Fruit{
public void eat();
}
class Apple implements Fruit{
public void eat(){
System.out.println("吃蘋果");
}
}
class Orange implements Fruit{
public void eat(){
System.out.println("吃橘子");
}
}
class Factory{
public static Fruit getInstance(String name)throws Exception{
Fruit f = null
Fruit f = (Fruit)Class.forName(name).newInstance();
if(f!=null){
return f;
}
else return null;
}
private Factory(){}
}
public class FactoryDemo01{
public static void main(String args[])throws Exception{
Properties p = new Properties();
p.load(new FileInputStream("1.properties"));
String str = p.getProperty("apple");
Fruit f = Factory.getInstance(str);
f.eat();
}
}
1.properties程式碼:
apple=Apple
orange=Orange
相關文章
- Java反射機制Java反射
- Java核心反射機制Java反射
- java利器——反射機制Java反射
- Java的反射機制Java反射
- Java反射機制(轉)Java反射
- Java反射機制那些事Java反射
- Java 中的 反射機制Java反射
- Java反射機制簡答Java反射
- 說說 Java 反射機制Java反射
- JAVA(五)反射機制/AnnotationJava反射
- Java 反射機制分析指南Java反射
- Java 反射機制詳解Java反射
- Java中的類反射機制Java反射
- Java筆記-反射機制(一)Java筆記反射
- java進階(41)--反射機制Java反射
- 淺析java的反射機制Java反射
- Java註解與反射機制Java反射
- java反射機制的學習心得Java反射
- 關於Java中的反射機制Java反射
- Java基礎之反射機制(續)Java反射
- Java重點基礎:反射機制Java反射
- Java動態代理和反射機制Java反射
- Java 反射機制的三種方式Java反射
- Java 反射機制應用實踐Java反射
- Java反射機制應用實踐Java反射
- Java反射機制實現與原理Java反射
- java中的反射機制淺析Java反射
- Java 反射機制學習資料Java反射
- JAVA中的反射機制詳解Java反射
- 菜鳥學Java(十四)——Java反射機制(一)Java反射
- 菜鳥學Java(十五)——Java反射機制(二)Java反射
- JAVA的反射機制==>用反射分析類的實現Java反射
- Java 從入門到精通-反射機制Java反射
- 淺談Java的反射機制和作用Java反射
- 基礎篇:深入解析JAVA反射機制Java反射
- Java筆記-反射機制(三)-小demoJava筆記反射
- Java安全基礎之Java反射機制和ClassLoader類載入機制Java反射
- Java進階 | 泛型機制與反射原理Java泛型反射