java–基础–20.1–反射–基础
1、介绍
反射:就是通过class文件对象,去使用该文件中的成员变量,构造方法,成员方法。
1.1、测试用的类
public class User {
private String name;
int id;
public String password;
public User() {
}
private User(String name) {
this.name = name;
}
User(String name, int id) {
this.name = name;
this.id = id;
}
public User(String name, int id, String password) {
this.name = name;
this.id = id;
this.password = password;
}
public void method(String s) {
System.out.println("method ");
}
public void method2(String s) {
System.out.println("method2");
}
private void method3() {
System.out.println("method3");
}
public void method4() {
System.out.println("show4");
}
public String method5(String s) {
System.out.println("show5:"+s);
return s;
}
@Override
public String toString() {
return "Person [name=" + name + ", id=" + id + ", password=" + password
+ "]";
}
}
2、获取class文件对象的方式
public static void main(String[] args) throws ClassNotFoundException {
User user=new User();
Class c1=user.getClass();
Class c2=Class.forName("cn.User");
Class c3=User.class;
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c1==c2);
System.out.println(c3==c2);
}
输出:
class cn.User
class cn.User
class cn.User
true
true
3、获取构造方法并实例化
3.1、获取构造方法
- public Constructor[] getConstructors():所有公共构造方法
- public Constructor[] getDeclaredConstructors():所有构造方法
- public Constructor< T> getConstructor(Class< ?>… parameterTypes):通过参数类,以及参数的个数确定对应的构造方法
- public T newInstance(Object… initargs):通过构造方法来实例化类对象,Object是实例化参数
3.2、案例
public class Test {
public static void main(String[] args) throws Exception {
// 获取字节码文件对象
Class c=Class.forName("cn.User");
//所有公共构造方法
System.out.println("-------所有公共构造方法--------");
Constructor[] cons=c.getConstructors();
for (Constructor constructor : cons) {
System.out.println(constructor);
}
System.out.println("-------所有构造方法--------");
//所有构造方法
Constructor[] conAll=c.getDeclaredConstructors();
for (Constructor constructor : conAll) {
System.out.println(constructor);
}
// 获取单个构造方法
System.out.println("-------通过参数类,以及参数的个数确定对应的构造方法.----------");
Constructor constr1=c.getDeclaredConstructor();
Constructor constr2=c.getDeclaredConstructor(String.class,int.class,String.class);
Constructor constr3=c.getDeclaredConstructor(String.class,int.class);
Constructor constr4=c.getDeclaredConstructor(String.class);
System.out.println(constr1);
System.out.println(constr2);
System.out.println(constr3);
System.out.println(constr4);
//创建该构造方法的声明类的新实例, 通过构造方法对象创建对象
System.out.println("------通过构造方法来实例化类对象,Object是实例化参数--------");
Object o=constr2.newInstance("小妹",23,"深圳");
System.out.println(o);
//值为true则指示反射的对象在使用时应该取消Java语言访问检查。,
//因为该构造方法是私有private User(String name),暴力访问
constr4.setAccessible(true);
Object o1=constr4.newInstance("余");
System.out.println(o1);
}
}
输出:
-------所有公共构造方法--------
public cn.User()
public cn.User(java.lang.String,int,java.lang.String)
-------所有构造方法--------
public cn.User()
public cn.User(java.lang.String,int,java.lang.String)
cn.User(java.lang.String,int)
private cn.User(java.lang.String)
-------通过参数类,以及参数的个数确定对应的构造方法.----------
public cn.User()
public cn.User(java.lang.String,int,java.lang.String)
cn.User(java.lang.String,int)
private cn.User(java.lang.String)
------通过构造方法来实例化类对象,Object是实例化参数--------
Person [name=小妹, id=23, password=深圳]
Person [name=余, id=0, password=null]
4、获取成员变量并使用
4.1、获取成员变量
- Field[] getDeclaredFields():获取所声明的所有字段。 返回 Field 对象的一个数组
- Field[] getFields():获取所有可访问公共字段,返回一个包含某些 Field 对象的数组
- Field getDeclaredField(String name):获取指定已声明字段,返回一个 Field 对象
4.2、案例
public class Test2 {
public static void main(String[] args) throws Exception {
// 获取字节码文件对象
Class c = Class.forName("cn.User");
//获取所有可访问公共字段 ,返回一个包含某些 Field 对象的数组
System.out.println("------获取所有公共成员变量------");
Field[] fs=c.getFields();
for (Field f : fs) {
System.out.println(f);
}
// Field[] getDeclaredFields() 获取所声明的所有字段。 返回 Field 对象的一个数组
System.out.println("------获取所有的成员变量------");
Field[] fsAll=c.getDeclaredFields();
for (Field f : fsAll) {
System.out.println(f);
}
// 获取指定已声明字段,返回一个 Field 对象
System.out.println("------------");
Field f=c.getDeclaredField("name");
f.setAccessible(true);//暴力访问private String name
//获取构造方法
Constructor con=c.getDeclaredConstructor(String.class);
con.setAccessible(true);//暴力访问 private 构造
//通过构造方法实例化
Object obj=con.newInstance("哈德森");
System.out.println(obj);
//为实例化对象obj 的 f字段设置值
f.set(obj, "特朗普");
System.out.println(obj);
}
}
输出:
------获取所有公共成员变量------
public java.lang.String cn.User.password
------获取所有的成员变量------
private java.lang.String cn.User.name
int cn.User.id
public java.lang.String cn.User.password
------------
Person [name=哈德森, id=0, password=null]
Person [name=特朗普, id=0, password=null]
5、获取成员方法并使用
5.1、获取成员方法
- Method[] getMethods():获取自己的包括父亲的公共方法, 返回一个包含某些 Method 对象的数组
- Method[] getDeclaredMethods():获取自己的所有的方法,不包括父类, 返回 Method 对象的一个数组
- Method getDeclaredMethod(String methodName, Class< ?>… parameterTypes):返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。
- Object invoke(Object obj, Object… args):第一个参数表示实例化对象,第二参数表示调用该方法的实际参数,返回方法的返回值;
5.2、案例
// 获取字节码文件对象
Class c = Class.forName("cn.User");
获取自己的包括父亲的公共方法
System.out.println("-----获取自己的包括父亲的公共方法------");
Method[] ms=c.getMethods();
for (Method method : ms) {
System.out.println(method);
}
// 获取自己的所有的方法
System.out.println("---获取自己的所有的方法------");
Method[] msAll=c.getDeclaredMethods();
for (Method method : msAll) {
System.out.println(method);
}
System.out.println("-----返回一个指定已声明方法 method-------");
Method m=c.getDeclaredMethod("method", String.class);
Object obj=c.getConstructor().newInstance();
//为实例化对象obj的方法m,设置参数hello,并使用该方法
Object o=m.invoke(obj, "hello");//执行方法
System.out.println(o);
System.out.println("-----method5方法-----");
Method m1=c.getMethod("method5", String.class);
Object o1=m1.invoke(obj, "逗逼");//执行方法,o1是方法的返回值
System.out.println(o1);
System.out.println("----method3方法-------");
Method m2=c.getDeclaredMethod("method3");
m2.setAccessible(true);//暴力使用 私有方法 private void method3()
m2.invoke(obj);
System.out.println(m2);
}
输出:
-----获取自己的包括父亲的公共方法------
public java.lang.String cn.User.toString()
public void cn.User.method(java.lang.String)
public java.lang.String cn.User.method5(java.lang.String)
public void cn.User.method2(java.lang.String)
public void cn.User.method4()
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 final void java.lang.Object.wait() 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()
---获取自己的所有的方法------
public java.lang.String cn.User.toString()
public void cn.User.method(java.lang.String)
public java.lang.String cn.User.method5(java.lang.String)
private void cn.User.method3()
public void cn.User.method2(java.lang.String)
public void cn.User.method4()
-----返回一个指定已声明方法 method-------
method
null
-----method5方法-----
show5:逗逼
逗逼
----method3方法-------
method3
private void cn.User.method3()