java-反射基础入门

2 篇文章 0 订阅
1 篇文章 0 订阅

反射

反射是java中提供的一种机制,它允许我们在程序运行的时候,动态获取一个类中的基本信息,并且可以调用类中的属性,方法,构造器.

public class Student{
private String name;
int age;
public static int num;
public Student(){}
public Student(String name,int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String sayHello(String name){
return "hello! "+name;
}
}

我们除了使用眼睛看到这个类中的属性方法构造器之外,在代码运行的时候,也可以通过反射机制获取到这个类中的属性,方法,构造器,已经调用构造器和方法.

Class c = Class.forName("com.briup.demo.Student");
Field[] fields = c.getDeclaredFields();
for(Field f : fields){
System.out.println("属性的修饰符:"+Modifier.toString(f.getModifiers()));
System.out.println("属性的类型:"+f.getType().getName());
System.out.println("属性的名称:"+f.getName());
System.out.println("---------------------");
}

Class类型

java.lang.Class 是API中提供的一个类,它可以表示java中所有的类型,包括基本类型和引用类型.

getClass方法的返回类型就是Class,所以obj.getClass();这句代码的含义就是,返回obj引用在运行时所指向对象的实际类型.

Class类型可以表示基本类型,数组类型,接口类型,类类型,每种类型加载到内存之后,都会在内存中生成一个Class类型对象,这个对象就代表这个具体的java类型,并且保存这个类型中的基本信息.

注意:java中的每种类型都有且只有唯一的一个Class类型对象与之对应!并且在类加载的时候自动生成

获取基本类型的Class对象

只有一种: Class c = int.class;

获取接口类型的Class对象有两种方法

  • Class c1 = Action.class;

  • Class c2 = Class.forName(“com.briup.demo.Action”);

获取数组类的Class对象有两种方法

  • Class c1 = int[].class; int[] arr = new int[4];
  • Class c2 = arr.getClass();

获取类类型的Class对象有三种方法

  • Class c1 = Student.class;
  • Class c2 = Class.forName(“com.briup.demo.Student”);
  • Student stu = new Student(); Class c3 = stu.getClass();

可以看出,获取一个类型Class对象的途径一般有三种

  • 使用类型名称直接获取
  • -使用Class类中的静态方法forName获取
  • 使用对象调用getClass方法获取

获取类中声明的属性

  1. 获取类中public修饰的属性,也包括从父类中继承的public属性
  • Field[] getFields()

  • Field getFiled(String name)

  1. 获取类中声明的属性(包含私有的),但是不能获取从父类中继承过来的属性
  • Field[] getDeclaredFields()
  • Field getDeclaredField(String name)

java.lang.reflect.Field 表示类中的属性

获取类中的方法

  1. 获取当前类中的public方法,包含从父类中继承的public方法
  • Method[] getMethods()
  • Method getMethod(String name,Class<?>… parameterTypes)
  1. 获取当前类中声明的方法(包含私有的),但是不能获取从父类中继承过来的方法
  • Method[] getDeclaredMethods();
  • Method getDeclaredMethods(String name,Class<?>… parameterTypes);

获取类中声明的构造器

  1. 获取当前类中的public构造器
  • public Constructor[] getConstructors()

  • public Constructor getConstructor(Class… parameterTypes)

  1. 获取当前类中的所有构造器,包含私有
  • public Constructor[] getDeclaredConstructors()

  • public Constructor getDeclaredConstructor(Class… parameterTypes)

反射访问属性

public static void main(String[] args)throws Exception {
Student stu = new Student();
Class c = stu.getClass();
//获取类中名字叫name的属性
Field f1 = c.getDeclaredField("name");
//设置私有属性可以被访问,否则报错
f1.setAccessible(true);
//用反射的方式,给指定对象的name属性赋值
//相当于之前的stu.name = "tom";
f1.set(stu,"tom");
//用反射的方式,获取这个属性的值
//相当于之前的stu.name
System.out.println(f1.get(stu));
System.out.println("----------------------");
//获取类中名字叫age的属性
Field f2 = c.getDeclaredField("age");
//用反射的方式,给指定对象的age属性赋值
//相当于之前的stu.age = 20;
f2.set(stu,20);
//用反射的方式,获取这个属性的值
//相当于之前的stu.age
System.out.println(f2.get(stu));
System.out.println("----------------------");
//获取类中名字叫num的属性
//4.6 反射调用方法
//注意, public Object invoke(Object obj, Object... args)
//obj,表示要调用哪个对象的方法,如果是静态方法,可以传null
//args,可变参数,表示要调用的方法的参数列表
m.invoke(obj,null) 中的m,就是通过Class对象获取到的类中的某一个指定的方法
//4.7 反射创建对象
//使用反射的方式可以创建对象,也就是需要反射调用构造器。
Field f3 = c.getDeclaredField("num");
//用反射的方式,给静态属性num赋值,不需要对象
//相当于之前的Student.num = 99;
f3.set(null,99);
//用反射的方式,获取这个静态属性的值,不需要对象
//相当于之前的Student.num
System.out.println(f3.get(null));
}

反射调用方法

public static void main(String[] args)throws Exception {
Student stu = new Student();
Class c = stu.getClass();
//获取类中的toString方法,没有参数,这是从父类继承的方法
Method m1 = c.getMethod("toString", null);
//反射的方式,调用stu对象中的这个方法,没有参数,并接收执行结果
//相当于之前的:Object result = stu.toString();
Object result = m1.invoke(stu,null);
//输出执行结果
System.out.println(result);
System.out.println("-------------------");
//获取类中的sayHello方法,需要一个String类型的参数,这是自己定义的方法
Method m2 = c.getMethod("sayHello", String.class);
//反射的方式,调用stu对象中的这个方法,参数是"tom",并接收执行结果
//相当于之前的:Object result = stu.sayHello("tom");
result = m2.invoke(stu,"tom");
//输出执行结果
System.out.println(result);
}

反射调用构造器

  1. 无参构造器
public static void main(String[] args)throws Exception {
Class c = Student.class;
//默认调用类中的无参构造器来创建对象
//相当于之前的:Object obj = new Student();
Object obj = c.newInstance();
System.out.println(obj);
}
  1. 有参构造器
public static void main(String[] args)throws Exception {
Class c = Student.class;
//获取类中的俩参构造器
Constructor constructor = c.getConstructor(String.class, int.class);
//调用有参构造器创建对象,并传入对应的参数值
//相当于之前的:Object obj = new Student("tom",20);
Object obj = constructor.newInstance("tom",20);
System.out.println(obj);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值