java反射

java反射

1、反射有什么用

​ 在程序运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。要想获取它的属性、方法,必须要先获取class字节码文件对象

2、反射怎么用

​ 既然反射可以直接操作字节码class文件,那么就需要先获取到它的字节码文件

2.1 获取class文件

需要获取class对象的类

public class Student {
    private String id;
    private String name;
    private String age;
    private String gender;

    public Student() {
    }

    public Student(String id, String name, String age, String gender) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.gender = gender;
    }
    // get、set、toString略
}

1、Class.forName(对象的全路径)

注意:这种获取class对象的方式会导致类加载,但是仅仅执行类的静态代码块

try {
    Class<?> studentClass1 = Class.forName("reflectTest.Student");
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}

2、对象.getClass()

Student student = new Student();
Class<? extends Student> studentClass2 = student.getClass();

3、任何类型.class

Class<Student> studentClass3 = Student.class;

2.2 使用字节码文件实例化对象

可以使用:class对象.newInstance() 来实例化一个对象

Student student1 = studentClass3.newInstance()

注意:newInstance()方法内部实际上调用了无参数构造方法,必须保证无参构造存在才可以

3、反编译(反射)一个类的属性

3.1 class

1、 创建对象

class.newInstance()

Student student = studentClass3.newInstance();

2、返回完整类名带包名

class.getName()

String name = studentClass3.getName();
System.out.println(name);
// --------输出结果------
reflectTest.Student

3、返回类名

class.getSimpleName()

String simpleName = studentClass3.getSimpleName();
System.out.println(simpleName);
// --------输出结果------
Student

4、返回类中public修饰的属性

class.getFields()

Field[] fields = studentClass3.getFields();

5、返回类中所有的属性

class.getDeclaredFields()

Field[] declaredFields = studentClass3.getDeclaredFields();
for (Field declaredField : declaredFields) {
    System.out.println(declaredField);
}
// --------输出结果------
private java.lang.String reflectTest.Student.id
private java.lang.String reflectTest.Student.name
private java.lang.String reflectTest.Student.age
private java.lang.String reflectTest.Student.gender

6、返回类中指定的属性

class.getDeclaredField(【属性名】)

Field id = studentClass3.getDeclaredField("id");
System.out.println(id);

7、获取属性的修饰符列表

class.getModifiers()

​ 返回的修饰符是一个数字,每个数字是修饰符的代号【一般配合Modifier类的toString(int x)方法使用】

​ 可以作用在类、属性、方法上

// 获取类的修饰符
int modifiers = studentClass3.getModifiers();
System.out.println(modifiers);
// --------输出结果------
1
/// 获取属性的修饰符
int modifiers = studentClass3.getDeclaredField("id").getModifiers();
System.out.println(modifiers);
// --------输出结果------
2
修饰符返回值
public1
private2
protected4
static8
final16
synchronized32
volatile64
transient128
native256
interface512
abstract1024
strict2048

8、返回类中所有实例方法

class.getDeclaredMethods()

Method[] declaredMethods = studentClass3.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
    System.out.println(declaredMethod);
}
//---------输出结果------------
public java.lang.String reflectTest.Student.toString()
public java.lang.String reflectTest.Student.getName()
public java.lang.String reflectTest.Student.getId()
public void reflectTest.Student.setName(java.lang.String)
public void reflectTest.Student.setId(java.lang.String)
public java.lang.String reflectTest.Student.getAge()
public java.lang.String reflectTest.Student.getGender()
public void reflectTest.Student.setGender(java.lang.String)
public void reflectTest.Student.setAge(java.lang.String)

9、返回类中所有的构造方法(class.getDeclaredConstructors())

Constructor<?>[] declaredConstructors = studentClass3.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
    System.out.println(declaredConstructor);
}
//---------输出结果------------
public reflectTest.Student()
public reflectTest.Student(java.lang.String,java.lang.String,java.lang.String,java.lang.String)

10、返回调用类的父类(class.getSuperclass())

Class<? super Student> superclass = studentClass3.getSuperclass();
System.out.println(superclass);
//---------输出结果------------
class java.lang.Object

11、返回调用类实现的接口集合(class.getInterfaces())

Class<?>[] interfaces = studentClass3.getInterfaces();
for (Class<?> anInterface : interfaces) {
    System.out.println(anInterface);
}
//--------Student没有实现接口,因此没有输出结果-----

3.2 Filed

获取Filed:

class.getDeclaredField(String name)

class.Field[] getDeclaredFields()

1、获取属性名

declaredField.getName()

Field field = studentClass3.getDeclaredField("id");
String name = field.getName();
System.out.println(name);
//---------输出结果------------
id

2、获取修饰符

​ 见3.1中的7

3、返回属性的数据类型

field.getType()

Class<?> type = field.getType();
System.out.println(type);
//---------输出结果------------
class java.lang.String

4、设置属性值

属性.set(对象, 值);

​ 利用反射为已经new出来的对象的指定的字段赋值

Student student = new Student();
// 获取属性的Filed
Field field = studentClass3.getDeclaredField("id");		// 获取student对象的id的filed
field.set(student,"我是id");	// 为对象student的id赋值
System.out.println(student.getId());
//---------输出结果------------
我是id

一般,private修饰的属性被封装起来,是不能够被访问的,在反射中可以打破封装,为private修饰的类进行赋值

Field gender = studentClass3.getDeclaredField("gender");
gender.setAccessible(true);		// 默认false,设置为true为打破封装
field.set(student,"男");
// ------如果不使用setAccessible,则会报错

在这里插入图片描述

5、读取属性值

属性.get(对象);

// 弄一个供测试使用的对象
Student student = new Student();
student.set("3131");
// 使用反射中的filed对象获取对象中存储的值
Field field = studentClass3.getDeclaredField("id");		// 获取student对象的id的filed
Object o = field.get(student);		// 获取student的id的值
System.out.println(o);
//---------输出结果------------
3131

3.3 Method

获取Method

public Method[] getDeclaredMethods()

public Method getDeclaredMethod(String name, Class<?>… parameterTypes)

1、返回方法名

declaredMethod.getName()

Method[] declaredMethods = studentClass3.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
    String name = declaredMethod.getName();
    System.out.println(name);
}
//---------输出结果------------
toString
getName
getId
setName
setGender
getGender
setId
setAge
getAge

2、获取方法的修饰符

​ 同3.1的第7条

3、获取方法的返回结果类型

method.getReturnType()

Method method = studentClass3.getDeclaredMethod("getAge");
Class<?> returnType = method.getReturnType();
System.out.println(returnType);
//---------输出结果------------
class java.lang.String

4、获取方法的入参类型

me.getParameterTypes()

Method me = studentClass3.getDeclaredMethod("setAge", String.class);
Class<?>[] parameterTypes = me.getParameterTypes();
for (Class<?> parameterType : parameterTypes) {
    System.out.println(parameterType);
}
//---------输出结果------------
class java.lang.String

5、调用方法

Method.invoke(对象, 实参);

Student student = new Student();
//使用反射调用对象的方法
Method me = studentClass3.getDeclaredMethod("setAge", String.class);
Object invoke = me.invoke(student, "53");
System.out.println(invoke);
System.out.println(student.getAge());
//---------输出结果------------
null
53

3.4 Constructor

public Constructor<?>[] getDeclaredConstructors()

public Constructor getDeclaredConstructor(Class<?>… parameterTypes)

1、获取构造名

Construct.getName()

Constructor<?>[] declaredConstructors = studentClass3.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
    System.out.println(declaredConstructor.getName());
    System.out.println(declaredConstructor);
    System.out.println("==========");
}
//---------输出结果------------
reflectTest.Student
public reflectTest.Student()
==========
reflectTest.Student
public reflectTest.Student(java.lang.String,java.lang.String,java.lang.String,java.lang.String)
==========

2、获取构造的修饰符

​ 同3.1的7

3、获取构造的形参数据类型列表

public Class<?>[] getParameterTypes()

Constructor<?>[] declaredConstructors = studentClass3.getDeclaredConstructors();
Constructor<?> declaredConstructor = declaredConstructors[1];
System.out.println(declaredConstructor);
Class<?>[] parameterTypes = declaredConstructor.getParameterTypes();
for (Class<?> parameterType : parameterTypes) {
    System.out.println(parameterType);
}
//---------输出结果------------
public reflectTest.Student(java.lang.String,java.lang.String,java.lang.String,java.lang.String)
class java.lang.String
class java.lang.String
class java.lang.String
class java.lang.String

4、创建对象

注意,括号中的参数为可选入参,如果要构建有参构造的对象,那么需要在括号中传入参数

public T newInstance(Object … initargs)

获取空参构造的反射,并创建对象

Constructor<?>[] declaredConstructors = studentClass3.getDeclaredConstructors();
Constructor<?> declaredConstructor = declaredConstructors[0];
Object o = declaredConstructor.newInstance();
System.out.println(o);
//---------输出结果------------
Student{id='null', name='null', age='null', gender='null'}

获取有参构造的反射,并创建对象

Constructor<?>[] declaredConstructors = studentClass3.getDeclaredConstructors();
Constructor<?> declaredConstructor = declaredConstructors[1];
Object o = declaredConstructor.newInstance("001","张三","32","男");
System.out.println(o);
//---------输出结果------------
Student{id='001', name='张三', age='32', gender='男'}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值