现在的位置: 首页 > 操作系统 > 正文

Java反射机制点滴知识

2020年02月06日 操作系统 ⁄ 共 6973字 ⁄ 字号 评论关闭

什么是反射

反射就是把Java类中的各个成分映射成一个个的Java对象。即在运行状态中,对于任意一个类,都能够知道这个类的所以属性和方法;对于任意一个对象,都能调用它的任意一个方法和属性。这种动态获取信息及动态调用对象方法的功能叫Java的反射机制。简单的说就是通过class文件对象,去使用该文件中的成员变量,构造方法,成员方法。

获取class文件对象的方式   

  Object类的getClass()方法  数据类型的静态属性class  Class类中的静态方法 public static Class forName(String className)

// 方式1 Person p = new Person(); Class c = p.getClass();

Person p2 = new Person(); Class c2 = p2.getClass();

System.out.println(p == p2);// false System.out.println(c == c2);// true

// 方式2 Class c3 = Person.class; // int.class; // String.class; System.out.println(c == c3);

// 方式3 // ClassNotFoundException Class c4 = Class.forName("renxixao.Person");    System.out.println(c == c4); } }

通过反射获取构造方法并使用

public class Person { private String name; int age; public String address;

public Person() { }

private Person(String name) { this.name = name; }

Person(String name, int age) { this.name = name; this.age = age; }

public Person(String name, int age, String address) { this.name = name; this.age = age; this.address = address; }

public void show() { System.out.println("show"); }

public void method(String s) { System.out.println("method " + s); }

public String getString(String s, int i) { return s + "---" + i; }

private void function() { System.out.println("function"); }

@Override public String toString() { return "Person [name=" + name + ", age=" + age + ", address=" + address + "]"; }

}

/** 通过反射获取构造方法并使用。*/public class ReflectDemo { public static void main(String[] args) throws Exception { // 获取字节码文件对象 Class c = Class.forName("renxixao.Person");

// public Constructor[] getConstructors():所有公共构造方法 Constructor[] constructors = c.getConstructors(); for (Constructor con : constructors) { System.out.println("公共构造方法:"+con); } // public Constructor[] getDeclaredConstructors():所有构造方法 Constructor[] declaredConstructors = c.getConstructors(); for (Constructor con : declaredConstructors) { System.out.println("所有构造方法:"+con); } // public Constructor<T> getConstructor(Class<?>... parameterTypes) 获取单个构造方法 // Class<?>... parameterTypes:获取的构造方法的构造参数个数及数据类型的class字节码文件对象 Constructor con = c.getConstructor();// 返回构造方法对象 // public T newInstance(Object... initargs) // 使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。 Object obj = con.newInstance(); System.out.println(obj); Person p = (Person)obj; p.show();     }}

运行结果

公共构造方法:public renxixao.Person(java.lang.String,int,java.lang.String)公共构造方法:public renxixao.Person()所有构造方法:public renxixao.Person(java.lang.String,int,java.lang.String)所有构造方法:public renxixao.Person()Person [name=null, age=0, address=null]show

/** 通过反射去获取该构造方法并使用:* public Person(String name, int age, String address)*/public class ReflectDemo2 { public static void main(String[] args) throws Exception { // 获取字节码文件对象 Class c = Class.forName("renxixao.Person"); // 获取带参构造方法对象 // public Constructor<T> getConstructor(Class<?>... parameterTypes) Constructor con = c.getConstructor(String.class, int.class, String.class); // 通过带参构造方法对象创建对象 // public T newInstance(Object... initargs) Object obj = con.newInstance("小明", 27, "北京"); System.out.println(obj); }}

Person [name=小明, age=27, address=北京]

通过反射获取私有构造方法并使用

/** 需求:通过反射获取私有构造方法并使用* private Person(String name){}*/public class ReflectDemo3 { public static void main(String[] args) throws Exception { // 获取字节码文件对象 Class c = Class.forName("renxixiao.Person");

// 获取私有构造方法对象 // NoSuchMethodException:每个这个方法异常 // 原因是一开始我们使用的方法只能获取公共的,下面这种方式就可以了。 Constructor con = c.getDeclaredConstructor(String.class);

// 用该私有构造方法创建对象 // IllegalAccessException:非法的访问异常。 // 暴力访问 con.setAccessible(true);// 值为true则指示反射的对象在使用时应该取消Java语言访问检查。 Object obj = con.newInstance("小明"); System.out.println(obj); }}

获取私有构造时必须设置 con.setAccessible(true) 否则出现 IllegalAccessException:非法的访问异常。

通过反射获取获取成员变量并使用

/** 通过发生获取成员变量并使用*/public class ReflectDemo { public static void main(String[] args) throws Exception { // 获取字节码文件对象 Class c = Class.forName("renxixiao.Person");

// 获取所有的成员变量 Field[] fields = c.getFields(); // 获取全部的成员变量 Field[] declaredFields = c.getDeclaredFields(); // 获取私有的成员变量 for (Field field : fields) { System.out.println("公共的成员变量"+field); } for (Field field : declaredFields) { System.out.println("私有的成员变量"+field); }

// 通过无参构造方法创建对象 Constructor con = c.getConstructor(); Object obj = con.newInstance();

// 获取单个的成员变量 // 获取address并对其赋值 Field addressField = c.getField("address"); // public void set(Object obj,Object value) 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。 addressField.set(obj, "北京"); // 给obj对象的addressField字段设置值为"北京" System.out.println(obj);

// 获取name并对其赋值 // NoSuchFieldException Field nameField = c.getDeclaredField("name"); // IllegalAccessException nameField.setAccessible(true); nameField.set(obj, "小明"); System.out.println(obj);

// 获取age并对其赋值 Field ageField = c.getDeclaredField("age"); ageField.setAccessible(true); ageField.set(obj, 27); System.out.println(obj); }}

全部的成员变量public java.lang.String renxixiao.Person.address私有的成员变量private java.lang.String renxixiao.Person.name私有的成员变量int renxixiao.Person.age私有的成员变量public java.lang.String renxixiao.Person.addressPerson [name=null, age=0, address=null]Person [name=null, age=0, address=北京]Person [name=小明, age=0, address=北京]Person [name=小明, age=27, address=北京]

通过反射获取获取方法并使用

/** 通过发生获取方法并使用*/public class ReflectDemo { public static void main(String[] args) throws Exception { // 获取字节码文件对象 Class c = Class.forName("renxixiao.Person");

// 获取所有的方法 Method[] methods = c.getMethods(); // 获取自己的包括父亲的公共方法 Method[] methodss = c.getDeclaredMethods(); // 获取自己的所有的方法 for (Method method : methods) { System.out.println("公共方法"+method); } for (Method method : methodss) { System.out.println("所有的方法"+method); } Constructor con = c.getConstructor(); Object obj = con.newInstance();

// 获取单个方法并使用 // public void show() // public Method getMethod(String name,Class<?>... parameterTypes) // 第一个参数表示的方法名,第二个参数表示的是方法的参数的class类型 Method m1 = c.getMethod("show"); // public Object invoke(Object obj,Object... args) // 返回值是Object接收,第一个参数表示对象是谁,第二参数表示调用该方法的实际参数 m1.invoke(obj); // 调用obj对象的m1方法 System.out.println("----------"); // public void method(String s) Method m2 = c.getMethod("method", String.class); m2.invoke(obj, "hello"); System.out.println("----------");

// public String getString(String s, int i) Method m3 = c.getMethod("getString", String.class, int.class); Object objString = m3.invoke(obj, "hello", 100); System.out.println(objString); // String s = (String)m3.invoke(obj, "hello",100); // System.out.println(s); System.out.println("----------");

// private void function() Method m4 = c.getDeclaredMethod("function"); m4.setAccessible(true); m4.invoke(obj); }}

公共方法public java.lang.String renxixiao.Person.toString()公共方法public java.lang.String renxixiao.Person.getString(java.lang.String,int)公共方法public void renxixiao.Person.method(java.lang.String)公共方法public void renxixiao.Person.show()公共方法public final void java.lang.Object.wait() throws java.lang.InterruptedException公共方法public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException公共方法public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException公共方法public boolean java.lang.Object.equals(java.lang.Object)公共方法public native int java.lang.Object.hashCode()公共方法public final native java.lang.Class java.lang.Object.getClass()公共方法public final native void java.lang.Object.notify()公共方法public final native void java.lang.Object.notifyAll()所有的方法public java.lang.String renxixiao.Person.toString()所有的方法private void renxixiao.Person.function()所有的方法public java.lang.String renxixiao.Person.getString(java.lang.String,int)所有的方法public void renxixiao.Person.method(java.lang.String)所有的方法public void renxixiao.Person.show()show----------method hello----------hello---100----------function

抱歉!评论已关闭.