1反射机制是什么
反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
2反射机制能做什么
反射机制主要提供了以下功能:
-
在运行时判断任意一个对象所属的类;
-
在运行时构造任意一个类的对象;
-
在运行时判断任意一个类所具有的成员变量和方法;
-
在运行时调用任意一个对象的方法;
-
生成动态代理。
3反射机制的相关API
①反射机制获取类有三种方法,例如获取User类
public static void main(String[] args) throws ClassNotFoundException {
Class<?> class1 = null;
Class<?> class2 = null;
Class<?> class3 = null;
// 第一种,一般采用这种形式
class1 = Class.forName("包名.User");
// 第二种
class2 = new User().getClass();
// 第三种
class3 = User.class;
System.out.println("类名称 " + class1.getName());
System.out.println("类名称 " + class2.getName());
System.out.println("类名称 " + class3.getName());
}
②获取一个对象的父类(getSuperclass())与实现的接口(getInterfaces())
public class Practice {
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("包名.Practice");
// 取得父类
Class<?> parentClass = clazz.getSuperclass();
System.out.println("clazz的父类为:" + parentClass.getName());
// clazz的父类为: java.lang.Object
// 获取所有的接口
Class<?> intes[] = clazz.getInterfaces();
System.out.println("clazz实现的接口有:");
for (int i = 0; i < intes.length; i++) {
System.out.println((i + 1) + ":" + intes[i].getName());
}
// clazz实现的接口有:
// 1:java.io.Serializable
}
}
③实例化默认构造方法(newInstance()),获取类中所有构造函数(getConstructors()),获取方法的参数类型(getParameterTypes())
public class Practice {
public static void main(String[] args) throws Exception {
Class<?> class1 = null;
class1 = Class.forName("pojo.User");
// 第一种方法,实例化默认构造方法,调用set赋值
User user = (User) class1.newInstance();
user.setAge(20);
user.setName("Rollen");
System.out.println(user);
// 结果 User [age=20, name=Rollen]
// 第二种方法 取得全部的构造函数 使用构造函数赋值
Constructor<?> cons[] = class1.getConstructors();
// 查看每个构造方法需要的参数
for (int i = 0; i < cons.length; i++) {
Class<?> clazzs[] = cons[i].getParameterTypes();
System.out.print("cons[" + i + "] (");
for (int j = 0; j < clazzs.length; j++) {
if (j == clazzs.length - 1)
System.out.print(clazzs[j].getName());
else
System.out.print(clazzs[j].getName() + ",");
}
System.out.println(")");
}
// 结果
// cons[0] (int,java.lang.String)
// cons[1] (java.lang.String)
// cons[2] ()
user = (User) cons[1].newInstance("Rollen");
System.out.println(user);
// 结果 User [age=0, name=Rollen]
user = (User) cons[0].newInstance(20, "Rollen");
System.out.println(user);
// 结果 User [age=20, name=Rollen]
}
}
public class User {
private int age;
private String name;
public User() {
super();
}
public User(String name) {
super();
this.name = name;
}
public User(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User [age=" + age + ", name=" + name + "]";
}
}
④getDeclaredField()方法获取一个类的所有字段,getField()获取类的public 字段,getModifiers()获取权限修饰符,getType()获取属性类型
public class Practice implements Serializable {
private static final long serialVersionUID = 1L;
private String name;
public String age;
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("test.Practice");
System.out.println("===============getDeclaredField是可以获取一个类的所有字段===============");
// 取得获取类的所有字段
Field[] field = clazz.getDeclaredFields();
for (int i = 0; i < field.length; i++) {
// 权限修饰符
int mo = field[i].getModifiers();
String priv = Modifier.toString(mo);
// 属性类型
Class<?> type = field[i].getType();
System.out.println(priv + " " + type.getName() + " " + field[i].getName() + ";");
}
System.out.println("==========getField只能获取类的public字段==========");
// 取得类的public字段
Field[] filed1 = clazz.getFields();
for (int j = 0; j < filed1.length; j++) {
// 权限修饰符
int mo = filed1[j].getModifiers();
String priv = Modifier.toString(mo);
// 属性类型
Class<?> type = filed1[j].getType();
System.out.println(priv + " " + type.getName() + " " + filed1[j].getName() + ";");
}
}
}
/*结果:
===============getDeclaredField是可以获取一个类的所有字段===============
private static final long serialVersionUID;
private java.lang.String name;
public java.lang.String age;
==========getField只能获取类的public字段==========
public java.lang.String age;*/
⑤获取类的全部方法(getMethods()),获取方法的参数类型(getParameterTypes()),获取方法返回类型(getReturnType())
public class Practice {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("test.Practice");
Method method[] = clazz.getMethods();
for (int i = 0; i < method.length; ++i) {
Class<?> returnType = method[i].getReturnType();
Class<?> para[] = method[i].getParameterTypes();
int temp = method[i].getModifiers();
System.out.print(Modifier.toString(temp) + " ");
System.out.print(returnType.getName() + " ");
System.out.print(method[i].getName() + " ");
System.out.print("(");
for (int j = 0; j < para.length; ++j) {
System.out.print(para[j].getName() + " " + "arg" + j);
if (j < para.length - 1) {
System.out.print(",");
}
}
Class<?> exce[] = method[i].getExceptionTypes();
if (exce.length > 0) {
System.out.print(") throws ");
for (int k = 0; k < exce.length; ++k) {
System.out.print(exce[k].getName() + " ");
if (k < exce.length - 1) {
System.out.print(",");
}
}
} else {
System.out.print(")");
}
System.out.println();
}
}
}
/*结果:
public static void main ([Ljava.lang.String; arg0) throws java.lang.Exception
public java.lang.String getName ()
public void setName (java.lang.String arg0)
public final void wait (long arg0,int arg1) throws java.lang.InterruptedException
public final native void wait (long arg0) throws java.lang.InterruptedException
public final void wait () throws java.lang.InterruptedException
public boolean equals (java.lang.Object arg0)
public java.lang.String toString ()
public native int hashCode ()
public final native java.lang.Class getClass ()
public final native void notify ()
public final native void notifyAll ()*/
⑥通过反射机制调用某个类的方法getMethod()
public class Practice {
private String name;
public static void main(String[] args) throws Exception {
Class<?> clazz = Class.forName("test.Practice");
// 调用TestReflect类中的reflect1方法
Method method = clazz.getMethod("reflect1");
method.invoke(clazz.newInstance());
// 调用TestReflect的reflect2方法
method = clazz.getMethod("reflect2", int.class, String.class);
method.invoke(clazz.newInstance(), 20, "张三");
}
public void reflect1() {
System.out.println("Java 反射机制 - 调用某个类的方法1.");
}
public void reflect2(int age, String name) {
System.out.println("Java 反射机制 - 调用某个类的方法2.");
System.out.println("age -> " + age + ". name -> " + name);
}
}
/*结果:
Java 反射机制 - 调用某个类的方法1.
Java 反射机制 - 调用某个类的方法2.
age -> 20. name -> 张三*/