黑马程序员技术交流社区
标题:
【记录】代码练习-反射
[打印本页]
作者:
Kevin.Kang
时间:
2015-8-11 15:55
标题:
【记录】代码练习-反射
简单来说反射就是通过class文件对象,去使用该文件中的成员变量,构造方法,成员方法。使用反射首先必须得到class文件对象,其实也就是得到Class类的对象。
package com.kxg_01;
/*
* 获取class文件对象的方式:
*
* 1.Object类的getClass()方法,返回是一个Class类。
* 2.数据类型的静态属性class
* 3.Class类中的静态方法:public static Class forName(String className)
*/
public class ClassDemo {
public static void main(String[] args) throws ClassNotFoundException {
// 方式1
Person p = new Person();
Class c = p.getClass();
// 方式2
Class c2 = Person.class;
// 方式3
Class c3 = Class.forName("com.kxg_01.Person");
}
}
class Person {
}
复制代码
作者:
Kevin.Kang
时间:
2015-8-11 16:25
本帖最后由 Kevin.Kang 于 2015-8-11 17:37 编辑
通过反射获取构造方法:
定义一个类:
package com.kxg_01;
public class Person {
private String name;
int age;
public String adress;
public Person() {
}
Person(String adress, int age) {
this.adress = adress;
this.age = age;
}
private Person(int age) {
this.age = age;
}
public Person(String name, int age, String adress) {
this.name = name;
this.adress = adress;
this.age = age;
}
public void show() {
System.out.println("show");
}
public void show2(String s) {
System.out.println("show2"+s);
}
public String show3(String s) {
return "show3:" + s;
}
private void show4(String s) {
System.out.println("show4");
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", adress=" + adress
+ "]";
}
}
复制代码
利用反射获取:
package com.kxg_01;
import java.lang.reflect.Constructor;
public class ClassDemo2 {
public static void main(String[] args) throws Exception{
// 获取字节码文件
Class c = Class.forName("com.kxg_01.Person");
// public Constructor[] getConstructors()
// 返回一个包含某些 Constructor 对象的数组,
// 这些对象反映此 Class 对象所表示的类的所有公共构造方法。也就是public修饰的构造方法
Constructor[] cons = c.getConstructors();
for (Constructor con : cons) {
System.out.println(con);
}
System.out.println("------------------------------------");
// public Constructor[] getDeclaredConstructors()
// 返回 Constructor 对象的一个数组, 这些对象反映此 Class 对象表示的类声明的所有构造方法。
// 它们是公共、保护、默认(包)访问和私有构造方法。
Constructor[] cons2 = c.getDeclaredConstructors();
for (Constructor con : cons2) {
System.out.println(con);
}
// public Constructor getConstructor(Class<?>... parameterTypes)
// 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法
// 参数表示的是你要获取的构造方法的构造参数个数以及数据类型的class字节码文件对象
Constructor con = c.getConstructor(String.class, int.class);
}
}
复制代码
作者:
Kevin.Kang
时间:
2015-8-11 16:29
本帖最后由 Kevin.Kang 于 2015-8-11 16:37 编辑
通过得到的构造方法创建对象
package com.kxg_01;
import java.lang.reflect.Constructor;
public class ClassDemo3 {
public static void main(String[] args) throws Exception{
// 使用Constructor类中的public T newInstance(Object... initargs)方法创建一个对象
Class c = Class.forName("com.kxg_01.Person");
// 获取无参构造,创建对象
Constructor con = c.getConstructor();
Object obj = con.newInstance(null);
System.out.println(obj);
// 获取有参构造,创建对象
Constructor con2 = c.getConstructor(String.class, int.class,
String.class);
Object obj2 = con2.newInstance("周星驰", 30, "中国");
System.out.println(obj2);
}
}
复制代码
作者:
Kevin.Kang
时间:
2015-8-11 16:47
获取私有构造方法并创建对象:
package com.kxg_01;
import java.lang.reflect.Constructor;
public class ClassDemo4 {
public static void main(String[] args) throws Exception {
// public Constructor getDeclaredConstructor(Class<?>...
// parameterTypes)
// Class类中的此方法可以获取任意修饰符修饰的构造方法
Class c = Class.forName("com.kxg_01.Person");
Constructor con = c.getDeclaredConstructor(int.class);
// 用私有方法创建对象,需要取消 Java 语言访问检查
// Constructor类的父类中public void setAccessible(boolean flag)
// 实现这个效果
con.setAccessible(true);
Object obj = con.newInstance(30);
System.out.println(obj);
}
}
复制代码
作者:
Kevin.Kang
时间:
2015-8-11 17:09
获取成员变量并进行赋值
package com.kxg_02;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class ReflectDemo {
public static void main(String[] args) throws Exception {
// 获取字节码文件对象
Class c = Class.forName("com.kxg_01.Person");
// public Field[] getDeclaredFields():获取全部成员变量对象数组
Field[] fields = c.getDeclaredFields();
for (Field f : fields) {
System.out.println(f);
}
System.out.println("-----------------------------");
// public Field getFields():获取成员变量对象数组,只能获取公共的
Field[] field = c.getFields();
for (Field f : field) {
System.out.println(f);
}
// public Field getField(String name):获取单个指定成员变量
Field adressField = c.getField("adress");
// 对成员变量进行赋值
// 使用Field类中的public void set(Object obj,Object value)方法
// 将指定对象变量上此 Field 对象表示的字段设置为指定的新值
// 想要为一个成员变量进行赋值,首先需要有一个对象
Constructor con = c.getConstructor();
Object obj = con.newInstance();
adressField.set(obj, "中国");// 给obj对象的adressField字段赋值为中国
System.out.println(obj);
}
}
复制代码
作者:
耀阳圣尊
时间:
2015-8-11 17:10
赞一个!!!!
作者:
Kevin.Kang
时间:
2015-8-11 17:33
本帖最后由 Kevin.Kang 于 2015-8-11 17:42 编辑
获取无参无返回值方法,并调用
package com.kxg_02;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class MethodDemo {
public static void main(String[] args) throws Exception {
Class c = Class.forName("com.kxg_01.Person");
// public Method[] getMethods():获取除了私有修饰的所有方法,包括从父类继承过来的
Method[] methods = c.getMethods();
for (Method m : methods) {
System.out.println(m);
}
System.out.println("-----------------------");
// public Method getMethod(String name,Class<?>... parameterTypes)
// 第一个参数是方法名,第二个参数是该方法参数的class类型,没有就不写,或者写null
Method m = c.getMethod("show", null);
// public Object invoke(Object obj,Object... args)
// 第一个参数是要调用方法的对象,第二个参数是该方法的实际参数,没有就不写,或者写null
// 创建对象
Constructor con = c.getConstructor();
Object obj = con.newInstance();
// 调用方法
m.invoke(obj, null);
}
}
复制代码
有参无返和有参有返案例
package com.kxg_02;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class MethodDemo2 {
public static void main(String[] args) throws Exception {
// 获取字节码文件对象
Class c = Class.forName("com.kxg_01.Person");
// 创建无参对象
Constructor con = c.getConstructor();
Object obj = con.newInstance();
// 获取有参无返回值方法
Method m = c.getMethod("show2", String.class);
// 获取有参有返回值方法
Method m2 = c.getMethod("show3", String.class);
// 调用方法
m.invoke(obj, "中国");
String s = (String) m2.invoke(obj, "河南");
System.out.println(s);
}
}
复制代码
作者:
风华正茂
时间:
2015-8-11 17:41
谢谢楼主分享,楼主辛苦了
作者:
artemiseven
时间:
2015-8-11 22:50
gaoduan aaa
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2