您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
【第15章:Java反射机制】_Java反射机制的深入研究
发布时间:2021-01-07 15:33:25编辑:雪饮阅读()
通过反射机制不用实例化一个类也可以直接调用类里面非静态方法
package org.kasumi;
import java.lang.reflect.Constructor ;
import java.lang.reflect.Modifier ;
import java.lang.reflect.Method ;
import java.lang.reflect.Field ;
interface China{
public static final String NATIONAL = "中国";
public static final String AUTHOR = "snowDrink";
public void sayChina();
public String sayHello(String name,int age);
}
interface Japan{
public static final String NATIONAL = "日本";
public static final String AUTHOR = "kasumi";
public void sayJapan();
}
class Monkey{}
class Person extends Monkey implements China,Japan{
private String name ;
private int age ;
public Person(){}
public Person(String name){this.name = name;}
public Person(String name,int age){this(name);this.age = age;}
public void sayChina(){
System.out.println("作者:" + China.AUTHOR + ",国籍:" + China.NATIONAL) ;
}
public String sayHello(String name,int age){
return name + ",你好!我今年:" + age + "岁了!" ;
}
public void sayJapan(){
System.out.println("作者:" + Japan.AUTHOR + ",国籍:" + Japan.NATIONAL) ;
}
public void setName(String name){this.name = name;}
public void setAge(int age){this.age = age ;}
public String getName(){return this.name;}
public int getAge(){return this.age;}
};
public class Hello{
public static void main(String args[]){
try{
Class<?> c1 = Class.forName("org.kasumi.Person") ;
Method met = c1.getMethod("sayChina") ;
met.invoke(c1.newInstance()) ;
}
catch(Exception e){}
}
};
对于有参的方法也同样可以调用
package org.kasumi;
import java.lang.reflect.Constructor ;
import java.lang.reflect.Modifier ;
import java.lang.reflect.Method ;
import java.lang.reflect.Field ;
interface China{
public static final String NATIONAL = "中国";
public static final String AUTHOR = "snowDrink";
public void sayChina();
public String sayHello(String name,int age);
}
interface Japan{
public static final String NATIONAL = "日本";
public static final String AUTHOR = "kasumi";
public void sayJapan();
}
class Monkey{}
class Person extends Monkey implements China,Japan{
private String name ;
private int age ;
public Person(){}
public Person(String name){this.name = name;}
public Person(String name,int age){this(name);this.age = age;}
public void sayChina(){
System.out.println("作者:" + China.AUTHOR + ",国籍:" + China.NATIONAL) ;
}
public String sayHello(String name,int age){
return name + ",你好!我今年:" + age + "岁了!" ;
}
public void sayJapan(){
System.out.println("作者:" + Japan.AUTHOR + ",国籍:" + Japan.NATIONAL) ;
}
public void setName(String name){this.name = name;}
public void setAge(int age){this.age = age ;}
public String getName(){return this.name;}
public int getAge(){return this.age;}
};
public class Hello{
public static void main(String args[]){
try{
Class<?> c1 = Class.forName("org.kasumi.Person");
Method met = c1.getMethod("sayHello",String.class,int.class) ;
String rv = (String)met.invoke(c1.newInstance(),"kasumi",24);
System.out.println(rv) ;
}
catch(Exception e){
e.printStackTrace() ;
}
}
};
D:\>javac -d . Hello.java
D:\>java org.kasumi.Hello
kasumi,你好!我今年:24岁了!
利用反射机制模拟实现java的getter与setter原理
package org.kasumi;
import java.lang.reflect.Constructor ;
import java.lang.reflect.Modifier ;
import java.lang.reflect.Method ;
import java.lang.reflect.Field ;
interface China{
public static final String NATIONAL = "中国";
public static final String AUTHOR = "snowDrink";
public void sayChina();
public String sayHello(String name,int age);
}
interface Japan{
public static final String NATIONAL = "日本";
public static final String AUTHOR = "kasumi";
public void sayJapan();
}
class Monkey{}
class Person extends Monkey implements China,Japan{
private String name ;
private int age ;
public Person(){}
public Person(String name){this.name = name;}
public Person(String name,int age){this(name);this.age = age;}
public void sayChina(){
System.out.println("作者:" + China.AUTHOR + ",国籍:" + China.NATIONAL) ;
}
public String sayHello(String name,int age){
return name + ",你好!我今年:" + age + "岁了!" ;
}
public void sayJapan(){
System.out.println("作者:" + Japan.AUTHOR + ",国籍:" + Japan.NATIONAL) ;
}
public void setName(String name){this.name = name;}
public void setAge(int age){this.age = age ;}
public String getName(){return this.name;}
public int getAge(){return this.age;}
};
public class Hello{
public static void main(String args[]){
try{
Class<?> c1 = Class.forName("org.kasumi.Person") ;
Object obj = c1.newInstance() ;
// 调用setter方法
//属性所属对象 属性名 属性值 属性类型
setter(obj,"name","kasumi",String.class) ;
setter(obj,"age",24,int.class) ;
System.out.print("姓名:") ;
// 调用getter方法
//属性所属对象 属性名
getter(obj,"name") ;
System.out.print("年龄:") ;
getter(obj,"age");
}catch(Exception e){}
}
/**
Object obj:要操作的对象
String att:要操作的属性
Object value:要设置的属性内容
Class<?> type:要设置的属性类型
*/
public static void setter(Object obj,String att,Object value,Class<?> type){
try{
Method met = obj.getClass().getMethod("set"+initStr(att),type) ; // 得到setter方法
met.invoke(obj,value) ; // 设置setter的内容
}catch(Exception e){
e.printStackTrace() ;
}
}
public static void getter(Object obj,String att){
try{
// 得到getter方法
Method met = obj.getClass().getMethod("get"+initStr(att)) ;
// 调用getter取得内容
System.out.println(met.invoke(obj)) ;
}catch(Exception e){
e.printStackTrace() ;
}
}
// 将单词的首字母大写
public static String initStr(String old){
//首字母大写然后追加原来非首字母
String str = old.substring(0,1).toUpperCase() + old.substring(1) ;
return str ;
}
};
D:\>javac -d . Hello.java
D:\>java org.kasumi.Hello
姓名:kasumi
年龄:24
注意:
在第一例中用反射调用方法是这样的:
Class<?> c1 = Class.forName("org.kasumi.Person") ;
Method met = c1.getMethod("sayChina") ;
met.invoke(c1.newInstance()) ;
而在这里用反射调用方法以getter为例,是这样的
Method met = obj.getClass().getMethod("get"+initStr(att)) ;
System.out.println(met.invoke(obj)) ;
其实第一例代码合并下冗余应该是这样的
Class<?> c1 = Class.forName("org.kasumi.Person") ;
Method met = Class.forName("org.kasumi.Person").getMethod("sayChina") ;
met.invoke(c1.newInstance()) ;
所以最终调用方法时候invoke的时候都是以一个类的实例做为参数,而invoke的调用者,这里的met都是一个获取了具体方法名的Method实例对象
所以没有什么不同的地方,只是顺序不一致
利用反射实现属性的设置与获取
package org.kasumi;
import java.lang.reflect.Constructor ;
import java.lang.reflect.Modifier ;
import java.lang.reflect.Method ;
import java.lang.reflect.Field ;
interface China{
public static final String NATIONAL = "中国";
public static final String AUTHOR = "snowDrink";
public void sayChina();
public String sayHello(String name,int age);
}
interface Japan{
public static final String NATIONAL = "日本";
public static final String AUTHOR = "kasumi";
public void sayJapan();
}
class Monkey{}
class Person extends Monkey implements China,Japan{
private String name ;
private int age ;
public Person(){}
public Person(String name){this.name = name;}
public Person(String name,int age){this(name);this.age = age;}
public void sayChina(){
System.out.println("作者:" + China.AUTHOR + ",国籍:" + China.NATIONAL) ;
}
public String sayHello(String name,int age){
return name + ",你好!我今年:" + age + "岁了!" ;
}
public void sayJapan(){
System.out.println("作者:" + Japan.AUTHOR + ",国籍:" + Japan.NATIONAL) ;
}
public void setName(String name){this.name = name;}
public void setAge(int age){this.age = age ;}
public String getName(){return this.name;}
public int getAge(){return this.age;}
};
public class Hello{
public static void main(String args[]) throws Exception{
Class<?> c1 = Class.forName("org.kasumi.Person");
Object obj = c1.newInstance();
Field nameField =c1.getDeclaredField("name") ; // 取得name属性
Field ageField = c1.getDeclaredField("age") ; // 取得name属性
nameField.setAccessible(true) ; // 此属性对外部可见
ageField.setAccessible(true) ; // 此属性对外部可见
nameField.set(obj,"kasumi") ; // 设置name属性内容
ageField.set(obj,24) ; // 设置age属性内容
System.out.println("姓名:" + nameField.get(obj)) ;
System.out.println("年龄:" + ageField.get(obj)) ;
}
};
D:\>javac -d . Hello.java
D:\>java org.kasumi.Hello
姓名:kasumi
年龄:24
使用反射获取数组类型数据的相关信息及设置数组元素
package org.kasumi;
import java.lang.reflect.Constructor ;
import java.lang.reflect.Modifier ;
import java.lang.reflect.Method ;
import java.lang.reflect.Field ;
import java.lang.reflect.Array ;
interface China{
public static final String NATIONAL = "中国";
public static final String AUTHOR = "snowDrink";
public void sayChina();
public String sayHello(String name,int age);
}
interface Japan{
public static final String NATIONAL = "日本";
public static final String AUTHOR = "kasumi";
public void sayJapan();
}
class Monkey{}
class Person extends Monkey implements China,Japan{
private String name ;
private int age ;
public Person(){}
public Person(String name){this.name = name;}
public Person(String name,int age){this(name);this.age = age;}
public void sayChina(){
System.out.println("作者:" + China.AUTHOR + ",国籍:" + China.NATIONAL) ;
}
public String sayHello(String name,int age){
return name + ",你好!我今年:" + age + "岁了!" ;
}
public void sayJapan(){
System.out.println("作者:" + Japan.AUTHOR + ",国籍:" + Japan.NATIONAL) ;
}
public void setName(String name){this.name = name;}
public void setAge(int age){this.age = age ;}
public String getName(){return this.name;}
public int getAge(){return this.age;}
};
public class Hello{
public static void main(String args[]) throws Exception{
int temp[] = {1,2,3} ;// 声明一整型数组
Class<?> c = temp.getClass().getComponentType() ; // 取得数组的Class对象
System.out.println("类型:" + c.getName()) ; // 取得数组类型名称
System.out.println("长度:" + Array.getLength(temp)) ;
System.out.println("第一个内容:" + Array.get(temp,0)) ;
Array.set(temp,0,6) ;
System.out.println("第一个内容:" + Array.get(temp,0)) ;
}
};
D:\>javac -d . Hello.java
D:\>java org.kasumi.Hello
类型:int
长度:3
第一个内容:1
第一个内容:6
不限制类型(Object)的数组操作(读、写)
package org.kasumi;
import java.lang.reflect.Constructor ;
import java.lang.reflect.Modifier ;
import java.lang.reflect.Method ;
import java.lang.reflect.Field ;
import java.lang.reflect.Array ;
public class Hello{
public static void main(String args[]) throws Exception{
int temp[] = {1,2,3} ;// 声明一整型数组
int newTemp[] = (int []) arrayInc(temp,5) ; // 重新开辟空间5
print(newTemp) ;
System.out.println("\n-------------------------") ;
String t[] = {"kasumi","snowDrink","ayane"} ;
String nt[] = (String [])arrayInc(t,8) ;
print(nt) ;
}
public static Object arrayInc(Object obj,int len){
Class<?> c = obj.getClass() ;
Class<?> arr = c.getComponentType() ; // 得到数组的class对象
Object newO = Array.newInstance(arr,len) ; // 开辟新的大小
int co = Array.getLength(obj) ;
// 拷贝内容 从原数组的指定索引开始拷贝到对应新数组的指定索引并指定拷贝长度co
System.arraycopy(obj,0,newO,0,co) ;
return newO ;
}
public static void print(Object obj){ // 数组输出
Class<?> c = obj.getClass() ;
if(!c.isArray()){ // 判断是否是数组
return;
}
Class<?> arr = c.getComponentType() ;
System.out.println(arr.getName()+"数组的长度是:" + Array.getLength(obj)) ; // 输出数组信息
for(int i=0;i<Array.getLength(obj);i++){
System.out.print(Array.get(obj,i) + "、") ; // 通过Array输出
}
}
};
D:\>javac -d . Hello.java
D:\>java org.kasumi.Hello
int数组的长度是:5
1、2、3、0、0、
-------------------------
java.lang.String数组的长度是:8
kasumi、snowDrink、ayane、null、null、null、null、null、
关键字词:java,反射