(1)、反射的基础知识
JAVA反射机制可以说是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。
反射的基石: Class 字节码
得到这个类的字节码的实例对象有3种
类名.class 如,System.class;
对象.class 如p1.getClass();
Class.forName("java.lang.String");
package cn.oyb.fanshe;
public class fansheTest {
public static void main(String[] args) throws Exception {
String str1 = "abc";
Class cls1 = str1.getClass();
Class cls2 = String.class;
Class cls3 = Class.forName("java.lang.String");
System.out.println(cls1 == cls2); //true
System.out.println(cls2 == cls3); //true
System.out.println(cls1.isPrimitive());//是否是一个基本类型的字节码 //flase
System.out.println(int.class.isPrimitive()); //true
System.out.println(int.class == Integer.class); //false
System.out.println(int.class == Integer.TYPE); //基本类型可以写成这样 true
System.out.println(int[].class.isPrimitive()); //false
System.out.println(int[].class.isArray()); //数组的Class实例对象 true
}
}
(2)、反射加强知识
反射就是把Java类中的各种成分映射成相应的java类。
可以获取其中的变量属性(Field),方法(Method),构造方法(Constructor),修饰符(Modifier),包(Package)等信息。
1,得到某个类所有的构造方法
Constructor[] constructor = Class.forName("java.lang.Sting").getConstructor();
2,得到类中某一个构造方法 //获得方法时要用到类型
Constructor con1 = Class.forName("java.lang.String").getConstructor(String.class);
3,创造实例对象 //要用到上面
String str = (String)con1.newInstance(new String("abc"));
//这里该方法得到构造方法,然后用该构造方法创造实例对象。
Constructor constructor1 = String.class.getConstructor(String.class);
String str = (String) constructor1.newInstance(new String("abc"));
System.out.println(str);
Field类---成员变量属性的反射
package cn.oyb.fanshe;
public class ReflectTest {
private int x;
public int y;
public String str1 = "ball";
public String str2 = "basketball";
public String str3 = "itcast";
public ReflectTest(int x, int y) {
this.x = x;
this.y = y;
}
public String toString() {
return str1+":"+str2+":"+str3;
}
}
//获得其值的方法
ReflectTest pt1 = new ReflectTest(2,5);
Field fieldY = pt1.getClass().getField("y"); //y是public
System.out.println(fieldY.get(pt1));
Field fieldX = pt1.getClass().getDeclaredField("x");//x是private私有的
fieldX.setAccessible(true); //需要设置暴力反射
System.out.println(fieldX.get(pt1));
//把对象上所有的String成员变量中的"b"换成"a"//main StringReplace(pt1)
private static void StringReplace(Object obj) throws Exception {
Field[] fields = obj.getClass().getFields();
for(Field field : fields){
if(field.getType() == String.class){
String oldValue = (String) field.get(obj);
String newValue = oldValue.replace("b", "a");
field.set(obj, newValue);
}
}
}
Method类 ---代表某个类上的一个成员方法
----得到类中的某一个方法
Method method = Class.forName("java.lang.String").getMethod("方法名称",int.class); //int.class为该方法参数类型
---调用方法
method.invoke(对象,参数); //例如method.invoke(pt1,23);
//如果传递给Method对象的invoke()方法的一个参数为null,,,说明该Method对象对应的是一个静态方法
用反射方式执行某个类中的main方法
在类中再增加一个类
class Test{
public static void main(String[] args) {
for(String arg :args)
System.out.println(arg);
}
}
//用反射调用
String startmain = args[0]; //main中传入上面类名
Method mainMethod = Class.forName(startmain).getMethod("main", String[].class);
------------------------反射的基本操作实例-------------------------------------------------
Person.java
public class Person {
private String name;
private int age;
private static int total;
private Person() {
super();
total++;
}
private Person(String name, int age) {
super();
this.name = name;
this.age = 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 static int getTotal() {
return total;
}
public static void setTotal(int total) {
Person.total = total;
}
@Override
public String toString() {
return "name:"+name+",age:"+age;
}
}
测试类
public class TestReflection {
public static void main(String[] args) {
try {
Class<?> c = Person.class;
//解析属性
Field[] fs = c.getDeclaredFields();
for(Field f : fs){
System.out.println("-----------------------");
System.out.println("属性:"+f.toString());
System.out.println("/t数据类型:"+f.getType());
System.out.println("/t属性名称:"+f.getName());
int mod = f.getModifiers(); //返回这个字段的修饰符
System.out.println("/t属性修饰符:"+ Modifier.toString(mod));
}
//解析方法
Method[] ms = c.getDeclaredMethods();
for(Method m :ms){
System.out.println("-----------------------");
System.out.println("方法:"+m.toString());
System.out.println("/t方法名:"+m.getName());
int mod = m.getModifiers(); //返回这个字段的修饰符
System.out.println("/t方法修饰符:"+ Modifier.toString(mod));
System.out.print("/t方法参数列表:");
Class pts[] = m.getParameterTypes(); //参数列表
for(int i=0;i<pts.length;i++){
Class class1 = pts[i];
if(i!=0)
System.out.print(","); //这里标逗号,值得借鉴
System.out.print(class1);
}
System.out.println();
System.out.println("/t返回值类型:"+m.getReturnType());// 方法的返回值类型
}
System.out.println("-构造方法信息-----------------------------------");
//解析构造方法
Constructor[] cs = c.getConstructors();
for(Constructor con :cs){
System.out.println("-----------------------");
System.out.println("构造方法:"+con.toString());
System.out.println("/t构造方法名:"+con.getName());
int mod = con.getModifiers();
System.out.println("/t方法修饰符:"+ Modifier.toString(mod));
System.out.println("/t方法参数列表:");
Class pts[] = con.getParameterTypes(); //参数列表
for(int i=0;i<pts.length;i++){
Class class1 = pts[i];
if(i!=0)
System.out.print(","); //这里标逗号,值得借鉴
System.out.print(class1);
}
System.out.println();
}
System.out.println("------------------------------------");
//解析当前类型的父类
Class getSuper = c.getSuperclass();
System.out.println("当前父类:"+getSuper.toString());
System.out.println("----------------");
//当前实现的接口
Class[] interfaces = c.getInterfaces();
System.out.println("当前实现的所有接口:");
for(Class class1 : interfaces){
System.out.println(class1.toString()+"/t");
}
System.out.println("/n------------------------------------");
//当前所在包信息
Package p =c.getPackage();
System.out.println("当前所在包:"+c.toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
---------------------------2例---------------------------------------------------------------
User.java
public class User {
public String name;
public int age;
public static int total=10;
/* public User() {
super();
total++;
}*/
public User(String name, int age) {
super();
this.name = name;
this.age = age;
total++;
}
public void setAll(String name,int age){
this.name = name;
this.age = age;
}
public static void showTotal(){
System.out.println("int total showTotal,total="+total);
}
public String toString(){
return "用户名:"+name+",年龄:"+age;
}
}
测试
public class TestRefUer {
public static void main(String[] args) throws Exception {
User u1 = new User("dd", 33);
TestRefUer tf = new TestRefUer();
System.out.println("-------------------------------");
tf.mdf(u1, "name", "刷个");
tf.mdf(u1, "age", 13);
System.out.println(u1);
System.out.println("-------------------------------");
tf.mdf1("Reflect.User", "total", 44);
System.out.println("-------------------------------");
// Class[] argtype = new Class[]{String.class,int.class};
Class[] argtype = {String.class,int.class}; //同上...
Object[] argss = new Object[]{"王武",88};
tf.mdf2(u1, "setAll", argtype, argss);
System.out.println(u1);
System.out.println("-------------------------------");
tf.mdf4("Reflect.User", "showTotal", new Class[0], new Object[0]);
}
//直接操作对象属性
public void mdf(Object o,String fieldName,Object newValue) throws Exception{
Class c = o.getClass();
Field f = c.getField(fieldName);
Object field = f.get(o);
System.out.println("修改前:"+fieldName+"="+field);
f.set(o, newValue);
System.out.println("修改后:"+fieldName+"="+f.get(o));
}
//直接操作类属性
public void mdf1(String o,String fieldName,Object newValue) throws Exception{
Class c = Class.forName(o);
Field f = c.getField(fieldName);
Object field = f.get(o);
System.out.println("修改前:"+fieldName+"="+field);
f.set(c, newValue); //这里操作的是class对象
System.out.println("修改后:"+fieldName+"="+f.get(c));
}
//调用对象成员,赋值
public void mdf2(Object obj,String methodName,Class[] argType,Object[] args) throws Exception{
Class c = obj.getClass();
Method m = c.getMethod(methodName, argType);
Object result = m.invoke(obj, args);
//System.out.println(result);
}
//调用类成员方法
public void mdf4(String obj,String methodName,Class[] argType,Object[] args) throws Exception{
Class c = Class.forName(obj);
Method m = c.getMethod(methodName, argType);
Object result = m.invoke(null, args);
//System.out.println(result);
}
}
----------------------------------调用构造方法----------------------------------------------
import java.lang.reflect.Constructor;
public class TestRefUser2 {
public static void main(String[] args) {
Class c ;
try {
//调用有参构造方法
c = .User.class;
Class[] argTypes = {String.class,int.class}; //此处为User类的有参构造方法参数类型
Constructor cons = c.getConstructor(argTypes);
Object obj = cons.newInstance("中国",5333);
System.out.println(obj);
//调用无参
cons =c.getConstructor();
//等同cons = c.getConstructor(new Class[0]);
//cons = c.getConstructor(null);
obj = cons.newInstance();
System.out.println(obj);
//调用参构造方法2
obj = c.newInstance();
System.out.println(obj+"dd");
} catch (Exception e) {
}
}
}