反射Reflect镜面反射或照X光(透视)
获得一个类的定义信息
反射通过方法区加载的"类对象"来执行
java只要用到一个类,就会把类加载到内存方法区,生成一个特殊对象——类对象,所以方法区保存的都是类对象。通过类对象可以获得一个类的定义信息(就像给类照了透视reflect一样)。
获得一个类的定义信息
1.包名、类名
2.成员变量定义信息(包括私有变量)
3.构造方法定义信息
4.方法定义信息(普通方法)
反射新建对象
得到在方法区的类对象后可以用反射的方式在堆内存创建出它的实例出来
反射访问成员变量
私有变量也可以访问
反射调用成员方法
类对象Class(获得类对象)
1类名.class
2Class.forName("完整类名");-包名.类名
3实例.getClass()
包名、类名
Class c=...
c.getPackage().getName()
包名
c.getName()
完整类名
c.getSimpleName()
类名,不含包名
成员变量定义信息
getFields()
获得可见的成员变量,包含从父类继承的
getDeclaredFields()
获得本类定义的成员变量,不包含继承的,包含私有
getField(变量名)
getDeclaredField(变量名)
获得一个变量
构造方法的定义信息
getConstructors()
获得可见的构造方法
getDeclaredConstructors()
获得所有构造方法,包含私有
getConstructor(int.class,String.class)
getDeclaredConstructor(int.class,String.class)
获得一个构造方法
方法的定义信息
getMethods()
可见的方法,继承的方法
getDeclaredMethods()
本类定义的方法,不包含集成度,包含私有
getMethod(方法名,参数类型列表)
getDeclaredMethod(方法名,参数类型列表)
获得单个方法
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Scanner;
public class FanShe1 {
public static void main(String[] args) {
/**
* "java.lang.String" "java.util.Date" "java.util.ArrayList"
* "java.io.File" "java.io.FileInputStream"
*/
System.out.print("输入类名:");
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
try {
// <?> 不知道是什么类型
Class<?> c = Class.forName(s);
System.out.println("包名 " + c.getPackage().getName());
System.out.println("完整类名 " + c.getName());
System.out.println("类名 " + c.getSimpleName());
System.out.println("====================");
System.out.println("成员变量");
fChengYuan(c);
System.out.println("====================");
System.out.println("构造方法");
fGouZao(c);
System.out.println("====================");
System.out.println("方法");
fFangFa(c);
} catch (ClassNotFoundException e) {
}
sc.close();
}
// 1
private static void fChengYuan(Class<?> c) {
// Field[]封装了变量的定义信息
Field[] a = c.getDeclaredFields();
/**
* public static final[修饰符] Date[数据类型] d[变量名]
*/
for (Field f : a) {
String m = Modifier.toString(f.getModifiers());
// 类型
String t = f.getType().getSimpleName();
// 变量名
String n = f.getName();
System.out.println(m + " " + t + " " + n);
}
}
// 2
private static void fGouZao(Class<?> c) {
/**
* public[修饰符] A[名字](int a,String b)[参数类型列表]throws A,B,C[异常类型列表]
*/
Constructor<?>[] a = c.getDeclaredConstructors();
for (Constructor<?> t : a) {
String m = Modifier.toString(t.getModifiers());
// 构造方法名,其实也是类名
String n = c.getSimpleName();
// 参数类型列表
Class<?>[] p = t.getParameterTypes();
System.out.println(m + " " + n + "(" + Arrays.toString(p) + ")");
}
}
// 3
private static void fFangFa(Class<?> c) {
/**
* public[修饰符] String[返回类型] A[名字](int a,String b)[参数类型列表]throws
* A,B,C[异常类型列表]
*/
Method[] a = c.getMethods();
for (Method t : a) {
// 修饰符
String m = Modifier.toString(t.getModifiers());
// 获得返回类型
String r = t.getReturnType().getSimpleName();
// 构造方法名,其实也是类名
String n = t.getName();
// 参数类型列表
Class<?>[] p = t.getParameterTypes();
Class<?>[] e = t.getExceptionTypes();
if (e.length == 0)
System.out.println(m + " " + r + " " + n + "("
+ Arrays.toString(p) + ")");
else
System.out.println(m + " " + r + " " + n + "("
+ Arrays.toString(p) + ")" + "throws"
+ Arrays.toString(e));
}
}
}
运行结果
输入类名:java.lang.reflect.Field
包名 java.lang.reflect
完整类名 java.lang.reflect.Field
类名 Field
====================
成员变量
private Class clazz
private int slot
private String name
private Class type
private int modifiers
private transient String signature
private transient FieldRepository genericInfo
private byte[] annotations
private FieldAccessor fieldAccessor
private FieldAccessor overrideFieldAccessor
private Field root
private transient Map declaredAnnotations
====================
构造方法
Field([class java.lang.Class, class java.lang.String, class java.lang.Class, in
t, int, class java.lang.String, class [B])
====================
方法
public Object get([class java.lang.Object])throws[class java.lang.IllegalArgumen
tException, class java.lang.IllegalAccessException]
public boolean equals([class java.lang.Object])
public String toString([])
public int hashCode([])
public int getModifiers([])
public boolean getBoolean([class java.lang.Object])throws[class java.lang.Illega
lArgumentException, class java.lang.IllegalAccessException]
public byte getByte([class java.lang.Object])throws[class java.lang.IllegalArgum
entException, class java.lang.IllegalAccessException]
public short getShort([class java.lang.Object])throws[class java.lang.IllegalArg
umentException, class java.lang.IllegalAccessException]
public char getChar([class java.lang.Object])throws[class java.lang.IllegalArgum
entException, class java.lang.IllegalAccessException]
public int getInt([class java.lang.Object])throws[class java.lang.IllegalArgumen
tException, class java.lang.IllegalAccessException]
public long getLong([class java.lang.Object])throws[class java.lang.IllegalArgum
entException, class java.lang.IllegalAccessException]
public float getFloat([class java.lang.Object])throws[class java.lang.IllegalArg
umentException, class java.lang.IllegalAccessException]
public double getDouble([class java.lang.Object])throws[class java.lang.IllegalA
rgumentException, class java.lang.IllegalAccessException]
public String getName([])
public Annotation getAnnotation([class java.lang.Class])
public Annotation[] getDeclaredAnnotations([])
public Class getDeclaringClass([])
public boolean isSynthetic([])
public Type getGenericType([])
public Class getType([])
public boolean isEnumConstant([])
public void set([class java.lang.Object, class java.lang.Object])throws[class ja
va.lang.IllegalArgumentException, class java.lang.IllegalAccessException]
public void setBoolean([class java.lang.Object, boolean])throws[class java.lang.
IllegalArgumentException, class java.lang.IllegalAccessException]
public void setByte([class java.lang.Object, byte])throws[class java.lang.Illega
lArgumentException, class java.lang.IllegalAccessException]
public void setChar([class java.lang.Object, char])throws[class java.lang.Illega
lArgumentException, class java.lang.IllegalAccessException]
public void setDouble([class java.lang.Object, double])throws[class java.lang.Il
legalArgumentException, class java.lang.IllegalAccessException]
public void setFloat([class java.lang.Object, float])throws[class java.lang.Ille
galArgumentException, class java.lang.IllegalAccessException]
public void setInt([class java.lang.Object, int])throws[class java.lang.IllegalA
rgumentException, class java.lang.IllegalAccessException]
public void setLong([class java.lang.Object, long])throws[class java.lang.Illega
lArgumentException, class java.lang.IllegalAccessException]
public void setShort([class java.lang.Object, short])throws[class java.lang.Ille
galArgumentException, class java.lang.IllegalAccessException]
public String toGenericString([])
public Annotation[] getAnnotations([])
public boolean isAnnotationPresent([class java.lang.Class])
public boolean isAccessible([])
public static void setAccessible([class [Ljava.lang.reflect.AccessibleObject;, b
oolean])throws[class java.lang.SecurityException]
public void setAccessible([boolean])throws[class java.lang.SecurityException]
public final void wait([long, int])throws[class java.lang.InterruptedException]
public final native void wait([long])throws[class java.lang.InterruptedException
]
public final void wait([])throws[class java.lang.InterruptedException]
public final native Class getClass([])
public final native void notify([])
public final native void notifyAll([])
反射新建实例
执行无参构造
Object obj=c.newInstance()
执行有参构造
1.获得构造方法
Constructor t=c.getConstructor(int.class,String.class)
2.通过执行指定构造方法,新建实例
Object obj=t.newInstance(5,"abc")
package reflect;
public class Student {
int age;
public Student() {
System.out.println("无参数构造");
}
public Student(int age) {
this.age = age;
System.out.println("有参数构造,int参数为"+age);
}
}
//======================================
package reflect;
import java.lang.reflect.Constructor;
import java.util.Scanner;
public class Test2FanShe {
public static void main(String[] args) {
System.out.println("输入类名");
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
sc.close();
Class<?> c = null;
try {
c = Class.forName(s);
} catch (ClassNotFoundException e1) {
System.out.println("找不到类");
}
Object o1;
Object o2;
try {
//新建实例并执行无参数构造方法
o1=c.newInstance();
System.out.println(o1);
} catch (Exception e) {
System.out.println("无法执行无参构造");
}
try {
//新建实例并执行int参数构造方法
Constructor<?> t = c.getConstructor(int.class);
o2 = t.newInstance(5);
System.out.println(o2);
} catch (Exception e) {
System.out.println("无法执行int参数构造");
}
}
}
运行结果
输入类名
reflect.Student
无参数构造
reflect.Student@65075056
有参数构造,int参数为5
reflect.Student@6fd5609
反射访问成员变量
获得变量的定义信息
Field f=c.getDeclaredField(变量名);
使私有变量可以被访问
f.setAccessible(true);
给变量赋值
f.set(实例,值)
需要指定实例,给指定的实例变量赋值、
静态变量,第一个参数给null
获得变量的值
f.get(实例)
获得指定实例中,这个变量的值
静态变量,第一个参数给null
import java.lang.reflect.Field;
public class FangWenBianLiang {
public static void main(String[] args) {
//Integer 里有成员变量value 保存着被封装的基本类型值
try {
Class<Integer> c=Integer.class;
Integer a=Integer.valueOf(40);
//获得私有成员变量value
Field f = c.getDeclaredField("value");
//使私有变量可以访问
f.setAccessible(true);
//获得变量的值
Object v = f.get(a);
System.out.println(v);
//修改a对象中,该变量的值
f.set(a, 444);
System.out.println(a);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
运行结果
40
444
反射调用方法
获取方法
Method m=c.getDeclaredMethod(方法名,参数类型列表);
使私有方法可以被调用
m.setAccessible(true);
调用方法
Object r=m.invole(实例,参数数据);
通过指定的实例,来执行这个方法
得到方法的返回值,保存到一个变量
void 方法会得到null
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;
public class Test4GetMethod {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Class<Date> c=Date.class;
Date d=new Date();
Method getTime = c.getMethod("getTime");
Method setTime = c.getMethod("setTime", long.class);
Object r = getTime.invoke(d);
System.out.println(r);
setTime.invoke(d, 9100000000L);
System.out.println(d);
}
}
运行结果
1532845616464
Thu Apr 16 15:46:40 CST 1970