Java-反射

反射

概述

  • 反射是Java系统的API 它允许程序在运行过程
  • 取得任何一个已知名称的类的内部信息,包括其中的构造方法,声明的字段和定义的方法等
  • 利用反射API可以实现动态执行
    - 动态加载类,获取信息
    - 动态创建对象
    - 动态访问属性
    - 动态调用方法
  • 动态执行 :只是在JVM运行期间才确定的执行次序
  • 静态执行:是指编译以后就确定了程序的运行次序,JVM运行期间按照既定的次序执行

反射API

Java反射API提供了动态执行能力
Class API:java.lang.Class,用于加载类和获取类的相关信息
Java反射API位于java.lang.reflect包中。主要包含以下几类:

  • Constructor类:用来描述一个类的构造方法
  • Field类:用来描述一个类的成员变量
  • Method类:用来描述一个类的方法
  • Modifier类:用来描述类内各元素的修饰符
  • Array:用来对数组进行操作

反射机制

java反射机制
反射是一种动态机制,允许我们实例化对象,调用方法,操作属性从编码期间确定转移到程序运行期确定。
因此反射提高了程序的灵活度,但是随之带来的是更多的系统开销和较慢的运行效率,因此反射机制不能过度的使用 。

获取利用反射操作的类的对象

  • Class实例:
    JVM中每个被加载的类都有且只有一个Class的实例与之对应,通过类对象(Class的实例)我们可以得知其表示的类的一切信息,例如:类名,有哪些属性,哪些方法,哪些构造器等等,并利用这些方法在程序运行期间操作它们。
    获取一个类的类对象有三种方式:
  • 类名.class
    例如:Class cls = String.class;
    Class cls = int.class;
  • Class.forName(String className)
    例如:Class cls =Class.forName(“java.lang.String”);
    这里forName方法中传入的是类的完全限定名,格式为:包名. 类名
  • 类加载器ClassLoader运行加载并获取
    优点:简单,直接 缺点:硬编码获取,不灵活
  • 获取所有公开方法
    Method[] methods = cls.getMethods();
  • 获取到本类自己定义的方法,包括私有方法
    Method[] methods = cls.getDeclaredMethods();
    上述代码:
try {
//			Class cls = Class.forName("java.util.HashMap");
			Scanner scanner = new Scanner(System.in);
			System.out.println("请输入一个类名:");
			String className = scanner.nextLine();
			Class cls = Class.forName(className);
			String name = cls.getName();
			System.out.println(name);
			//获取String中所有公开方法
//			Method[] methods = cls.getMethods();
			//获取到本类自己定义的方法,包括私有方法
			Method[] methods = cls.getDeclaredMethods();
			for(Method method : methods) {
				System.out.println(method.getName());
			}
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

利用反射进行实例化操作

new关键字
Person p = new Person();
System.out.println(p);
利用反射实例化

(1)加载类的类对象

Class cls = Class.forName("reflect.Person");
		Object o = cls.newInstance();//必须有无参构造器
		System.out.println(o);

(2)利用反射调用私有成员

Person p = new Person();
//		p.dosome();编译不通过
		Class<?> cls = Class.forName("reflect.Person");
		Object o = cls.newInstance();
		//获取Person中的私有方法dosome
		Method m = cls.getDeclaredMethod("dosome");
		m.setAccessible(true);
		m.invoke(o);

(3)通过指定的构造器实例化对象

Person p = new Person();
	System.out.println(p);
	Person p1 = new Person("李四",55);
	System.out.println(p1);
	Class<?> cls = Class.forName("reflect.Person");
	//获取构造器(无参构造器)
	Constructor<?> c = cls.getConstructor();
	//利用该构造器实例化对象
	Object o = c.newInstance();
	System.out.println(o);
	//利用Person(String,int)
	Constructor<?> c2 = cls.getConstructor(String.class,int.class);
	//实例化
	Object o2 = c2.newInstance("西瓜",18);
	System.out.println(o2);

(4)使用反射机制调用方法

	Person p = new Person();
		p.sayHello();
		Scanner scanner = new Scanner(System.in);
		System.out.println("请输入类名:");
		String className = scanner.nextLine();
		System.out.println("请输入方法名:");
		String methodName = scanner.nextLine();
		//实例化
		Class<?> c = Class.forName(className);
		Object o = c.newInstance();//Person o = new Person();
		//获取sayHello方法并调用
		Method m = c.getMethod(methodName);
		//Method提供了一个动态执行一个方法的方法:Object invoke(Object obj,Object..args)
		m.invoke(o);//o.sayHello();
		System.out.println("aaaaaaaaaaaaaaaaaaaaaaaa");

(5)调用有参方法

Person p = new 	Person();
	p.sayHello("大家好!");
	p.say("Carry", 18);
	Class cls = Class.forName("reflect.Person");
	Object o = cls.newInstance();
	//sayHello(String)
	Method m = cls.getMethod("sayHello", String.class);
	m.invoke(o, "哈喽~");
	Method m1 = cls.getMethod("say", String.class,int.class);
	m1.invoke(o, "兔子",22);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值