1 反射概述
反射: 根据Class对象,操作Class对象中的成员.
2 反射获取Class对象
获取Class对象的方法:
- new 对象 调用getClass()获取(Object中提供方法)
- 类名.class 每个数据类型,不管是基本还是引用类型,jvm都赋予了一个静态属性,名字叫做class
- Class中方法 forName(String className) (常用)
==ps: class仅仅只加载一次,Class对象也只有一个,用方法三,获取的Class对象是同一个==
package com.cf;
public class User {
private String name;
private int age;
public User() {
}
public User(String name) {
this.name = name;
System.out.println("私有构造");
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public static void main(String[] args) throws ClassNotFoundException {
//每个数据类型,不管基本还是引用数据类型,jvm都赋予了这个类型一个静态属性,名字叫class
Class aClass = User.class;
Class aClass1 = Class.forName("com.cf.User");
//Object类中的getClass方法
User user = new User();
Class aClass2 = user.getClass();
System.out.println(aClass==aClass1);
System.out.println(aClass==aClass2);
}
}
/**
结果如下:
true
true
*/
3 获取Class对象成员
1 获取所有public构造
Constructor<?>[] getConstructors() 获取所有的public构造方法
public class Test{
public static void main(String[] args) throws ClassNotFoundException {
//获取User类的Class对象
Class pClass = Class.forName("com.cf.User");
Constructor[] constructors = pClass.getConstructors();
//遍历数组
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
}
}
/**
结果如下:
public com.cf.User()
public com.cf.User(java.lang.String,int)
私有构造没有获取到.
*/
2 获取空参构造
Constructor<T> getConstructor(Class<?>... parameterTypes) 获取指定的构造方法,没有传参,表示无参构造
T newInstance(Object...initargs) 根据构造方法创建对象,空参构造不需要传参数
public class Test2{
public static void main(String[] args) throws Exception {
// 获取User类的Class对象
Class pClass = Class.forName("com.cf.User");
// 获取无参构造
Constructor constructor = pClass.getConstructor();
// 类似 User user = new User()
Object o = constructor.newInstance();
System.out.println(o);
}
}
/**
结果如下:
User{name='null', age=0}
*/
3 利用空参快速创建对象
直接使用Class类中的newInstance方法
==tip: 被反射的类, 必须要有public权限的空参构造==
public class Test3{
public static void main(String[] args) throws Exception {
// 获取User类的Class对象
Class pClass = Class.forName("com.cf.User");
Object o = pClass.newInstance();
System.out.println(o);
}
}
/**
结果如下:
User{name='null', age=0}
*/
4 使用反射获取有参构造创建对象
Constructor<T> getConstructor(Class<?>... parameterTypes) 获取指定的构造方法,没有传参,表示无参构造
T newInstance(Object...initargs) 根据构造方法创建对象,空参构造不需要传参数
public class Test4{
public static void main(String[] args) throws Exception{
//获取User类的Class对象
Class pClass = Class.forName("com.cf.User");
//获取有参构造
Constructor constructor = pClass.getConstructor(String.class, int.class);
System.out.println(constructor);
//创建对象
Object o = constructor.newInstance("杨幂", 18);
System.out.println(o);
}
}
/**
结果如下:
public com.cf.User(java.lang.String,int)
User{name='杨幂', age=18}
*/
5 使用反射获取私有构造(暴力反射)
Constructor<?>[] getDeclaredConstructors() 获取所有的构造,包括私有的
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 获取指定的构造
void setAccessible(boolean flag) AccessibleObject类的方法,flag为false,表示不能访问私有的成员,为true,表示可以访问.(暴力反射)
public class Test5{
public static void main(String[] args) throws Exception{
//获取User类的Class对象
Class pClass = Class.forName("com.cf.User");
//获取私有的构造方法
Constructor dds = pClass.getDeclaredConstructor(String.class);
//解除私有权限
dds.setAccessible(true);
//创建对象
Object o = dds.newInstance("郭襄");
System.out.println(o);
}
}
/**
结果如下:
私有构造
User{name='郭襄', age=0}
*/
6 使用反射获取所有成员方法
Method[] getMethods() 获取所有的public方法
public class Test6{
public static void main(String[] args) throws Exception{
//获取User类的Class对象
Class c = Class.forName("com.cf.User");
Method[] methods = c.getMethods();
//遍历数组
for (Method method : methods) {
System.out.println(method);
}
}
}
/**
结果如下:
public static void com.cf.User.main(java.lang.String[]) throws java.lang.Exception
public java.lang.String com.cf.User.toString()
public java.lang.String com.cf.User.getName()
public void com.cf.User.setName(java.lang.String)
public void com.cf.User.setAge(int)
public int com.cf.User.getAge()
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()
*/
7 使用反射获取方法
Method getMethod(String name, Class<?>... parameterTypes) name:获取的方法名, parameterTypes:该方法的参数类型,如果获取的方法没有参数,parameterTypes不需要写.
Object invoke(Object obj, Object... args) obj:是调用newInstance方法生成的对象, args:运行方法时传递的实参
public class Test7{
public static void main(String[] args) throws Exception{
//获取User类的Class对象
Class c = Class.forName("com.cf.User");
System.out.println("---------获取setName方法-------------");
//获取set方法
Method setName = c.getMethod("setName", String.class);
//利用空参构造创建User对象
Object o = c.newInstance();
//调用方法
setName.invoke(o, "杨幂");
System.out.println(o);
System.out.println("---------获取getName方法-------------");
Method getName = c.getMethod("getName");
//执行getName方法,有返回值的
Object invoke = getName.invoke(o);
System.out.println(invoke);
}
}
/**
结果如下:
---------获取setName方法-------------
User{name='杨幂', age=0}
---------获取getName方法-------------
杨幂
*/