反射:
是通过对象去获得对象身后的信息;【本类的构造方法,普通方法,属性等等】
Class类:
-接口:Serializable, GenericDeclaration, Type, AnnotatedElement
-完成反射操作的核心类是Class类;
-每一个类都有它的唯一的Class对象,此对象在类加载时由JVM产生,用户只能获得,无法创建
【获得Class对象的三种方法】
1.通过Object提供的getClass()方法(此方法会产生此类的实例化对象)
2.通过 类.class
3.通过Class提供的ForName()方法
public static 类<?> forName(String className)throws ClassNotFoundException
public class TestDemo {
public static void main(String[] args) throws ClassNotFoundException {
Date date = new Date();
//1.Object类的getClass方法,此方法要先获得类的对象
System.out.println(date.getClass());
//类.class方法
System.out.println(Date.class);
//Class的forName方法
System.out.println(Class.forName("java.util.Date"));
}
}
拿到一个类的Class对象后
【1.通过反射实例化对象newInstance()】
public T newInstance() throws InstantiationException, IllegalAccessException
public class TestDemo {
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
Object cls = Date.class;
//拿到Class对象后,调用newInstance()方法
System.out.println(((Class) cls).newInstance());
}
}
【2.获得包名,父类,父接口信息】
1.获得包名—Class类提供的getPackage()方法
2.获得父类—Class类提供的getSuperclass()方法
3.获得父接口信息—Class类提供的getInterfaces()
interface Ilipstick{
}
interface Fruit{
}
class Person{
}
class Student extends Person{
}
class SuperMarker implements Ilipstick,Fruit{
}
public class TestJ{
public static void main(String[] args) {
//获得Class对象
Class<?> cls = Student.class;
Class<?> cl = SuperMarker.class;
//获得包信息
Package p = cls.getPackage();
System.out.println(p);
//获得父类信息
Class<?> c = cls.getSuperclass();
System.out.println(c.getName());
//获得父接口信息
Class[] g = cl.getInterfaces();
for (Class<?> class1 :g){
System.out.println(class1.getName());
}
}
}
【3.取得属性,构造方法,普通方法】
Person类,Student类:
class Person{
public String name;
public int age;
}
class Student {
public String School;
public String skill;
private int bob;
protected String sod;
public Student(){}
public Student(String name){}
public Student(String name ,int age){}
public void setSchool(String school) {
School = school;
}
public void setSkill(String skill) {
this.skill = skill;
}
public String getSchool() {
return School;
}
public String getSkill() {
return skill;
}
}
1.取得属性
(1)(父类中)-取得类中全部属性: public Field[] getFields() throws SecurityException
(2).(本类中)-取得类中全部属性: public Field[] getDeclaredFields() throws SecurityException
public class TestJ{
public static void main(String[] args) throws NoSuchFieldException, ClassNotFoundException {
Class<?> cls = Class.forName("Student");
{
//获得所有的"公有字段",也可取得父类的属性
Field[] fie1 = ((Class) cls).getFields();
for (Field fiel : fie1) {
System.out.println(fiel);
}
System.out.println("-----------------------------");
//取得所有的字段,包含被封装的
Field[] fie2 = ((Class) cls).getDeclaredFields();
for (Field field : fie2) {
System.out.println(field);
}
}
}
}
2.取得构造方法—Class类通过反射实例化类对象的时候,只能够调用类中的无参构造
-public Constructor<?>[] getConstructors() throws SecurityException
-public Constructor getConstructor(Class<?>… parameterTypes)
throws NoSuchMethodException, SecurityException
public class TestJ{
public static void main(String[] args) throws NoSuchFieldException, ClassNotFoundException {
Class<?> cls = Class.forName("Student");
//调用类中的全部构造方法
Constructor<?>[] cons = cls.getConstructors();
for(Constructor<?> con :cons){
System.out.println(con);
}
System.out.println("------------------");
//获得指定参数的构造方法
System.out.println(cls.getConstructor(String.class));
}
}
3.取得普通方法
-public Method[] getMethods() throws SecurityException
-public Method getMethod(String name, Class<?>… parameterTypes)
-调用public Object invoke(Object obj, Object… args)throws IllegalAccessException,
IllegalArgumentException,InvocationTargetException
public class TestJ{
public static void main(String[] args) throws NoSuchFieldException, ClassNotFoundException {
Class<?> cls = Class.forName("Student");
//调用类中的全部普通方法
Method[] methods = cls.getMethods();
for(Method method : methods){
System.out.println(method);
}
System.out.println("------------------");
//获得指定普通方法
System.out.println(cls.getMethod("setSkill", String.class));
System.out.println("------------------");
//调用invoke()方法
//获得setSchool这个方法的实例化对象,设置方法名与参数
Method setMethod = cls.getMethod("setSchool", String.class);
//传入参数
setMethod.invoke(obj,"清华");
Method getMethod = cls.getMethod("getSchool");
Object result = getMethod.invoke(obj);
System.out.println(result);
}
}