Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

java学习笔记,反射及其引用

Java高级——反射

反射入门


java反射机制是在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法,对于任意一个对象,都能调用它的一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制

java反射机制主要提供了一下功能:

  1. 在运行时判断任意一个对象所属的类
  2. 在运行时构造任意一个类的对象
  3. 在运行时判断一个类所具有的成员变量和方法;
  4. 在运行时调用任意一个对象的方法;
  5. 生成动态代理;

反射API


我们写的所有类,都会被appclassloader加载到内存的方法区,生成一个Class类型的对象(万物皆对象(~ ̄▽ ̄)~),他们是我们写的class,同时也涉及Class实列。也叫说明书的说明书

Class叫说明书的说明书,告诉了我们怎么写说明书,比如可以有方法、属性等等

我们的class都是说明书,说明了某类对象所具有的方法和属性

Java反射需要的类主要有:

  1. java.lang.Class
  2. java.lang.reflect包中的
    1. Field
    2. Constructor
    3. Method
    4. Annotation

Class类是Java反射的起源,针对任何一个你想探测的类,只有先产生它的一个Class类对象,接下来才能通过Class对象获取其他想要的信息

获取对象的方法


1
2
3
4
5
6
7
8
9
//使用类
Class cla = Dog.class;

//使用全类名
Class aClass = Class.forName("com.ender.Day");

//使用对象
Cat cat = new cat();
Class cla = cat.getClass();

操作字段


获取字段

1
2
3
4
5
6
7
8
9
10
11
//只能获取到用public修饰的字段
Field[] fields = animalClass.getFields();
for (Field field : fields) {
System.out.println(field.getName());
}

//能获取到所有被声明了的字段
Field[] fields1 = animalClass.getDeclaredFields();
for (Field field : fields1) {
System.out.println(field.getName());
}

字段赋值


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
try {
field.set(animal, "张三");
System.out.println(field.get(animal));
} catch (IllegalAccessException e){
e.printStackTrace();
}

try {
Field field = animalClass.getDeclaredField("age");
field.setAccessible(true);//当在要操作类的文件夹之外的地方对私有字段注入值时,需要开启权限
field.set(animal,12);
System.out.println(field.get(animal));
} catch (NoSuchFieldException | IllegalAccessException e){
e.printStackTrace();
}

方法


获取方法


1
2
3
4
5
Method eat1 = animalClass.getMethod("eat");
Method eat2 = animalClass.getDeclaredMethod("eat");
Method eat = animalClass.getMethod("eat",String.class,int.class);//对于有参数的方法,需要如此获取,每个参数需要传入类型

Method methods[] = animalClass.getDeclaredMethods();
对方法的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Animal animal = new Animal();
animal.setName("ZhangSan");
animal.setAge(20);
Class<Animal> animalClass = Animal.class;
//获取某个方法,名字,后边是参数类型
Method method = animalClass.getMethod("eat",String.class,int.class);
//拿到参数的个数
int parameterCount = method.getParameterCount();
//拿到方法名字
String name = method.getName();
//拿到参数的类型数组
Class<?>[] parameterTypes = method.getParameterTypes();
//拿到返回值类型
Class<?> returnType = method.getReturnType();
//重点。反射调用方法,传一个实列,和参数
method.invoke(animal,"LiSi",20);

构造函数


1
2
3
4
Class animalClass = Class.forName("com.ender.Animal");
Constructor<Animal> constructor = animalClass.getConstructor();
Animal animal = constructor.newInstance();
animal.eat();
反射与注释
1
2
3
4
5
6
7
8
9
Animal animal = new Animal();
Class<Animal> animalClass = Animal.class;
A aannotation = animalClass.getAnnotation(A.class);//通过类获取该类的注释
Field name = animalClass.getDeclaredField("name");
name.setAccessible(true);//若该字段为私有,则需要以此设置访问权限,使得能够访问该字段的值
Name nameAnnotion = name.getAnnotation(Name.class);//通过某个字段获取该字段的注释
String fullName = nameAnnotion.name();//获取注释中的元素值
name.set(animal,fullName);
System.out.println(name.get(animal));

评论