Java反射总结

本文介绍了Java中的反射机制,包括反射的定义、应用和功能。详细讲解了Class类的使用,如何获取Class实例,以及通过Class对象获取类的基本信息、判断类型、创建实例和调用方法。还讨论了反射在处理多态问题时的行为。
摘要由CSDN通过智能技术生成

目录

1.反射的定义

2.反射的应用

3.反射的功能

4.Class类

4.1获取Class实例的方法:

4.2Class实例获取基本信息

4.3判断类型

4.4创建实例对象

5.常用方法

5.1获取构造方法

5.2访问字段(成员变量)

5.3获取所有的方法

5.4获取参数类型

5.5调用静态方法

6.多态问题
​​​​​​​​​​​​​​

1.反射的定义

反射的定义:反射是指在运行期,对于任意一个类都能动态的调用信息及获取对象,即知道任意类的属性和方法,调用任意对象的方法和属性。

运行期是指将便后后的文件交给计算机执行,知道执行完毕,也就是将文件从磁盘上读取到内存中的过程。

2.反射的应用

反射主要应用在服务器和中间件程序之间得到广泛应用,而且还应用于各大煮酒框架中。如:在ORM框架的实现中,应用反射机制读取任意一个JavaBean对象的属性,给这些属性赋值。

3.反射的功能

(1)在运行时,判断任意一个对象所属的类。

(2)在运行时,为某个类构造对象。

(3)判断任意一个类的成员变量和方法。

(4)调用任意一个对象的方法。

(5)生成动态代理。

4.Class类

要想知道一个类的属性和方法,必须先获取该类的字节码文件,使用的就是Class类中的对象

classsJVM在执行过程中动态加载的,每读取一中class类型就会将其加载进内存,然后为其创建一个Class实例,并关联起来,每种不同类型的类都有一个Class实例。

4.1获取Class实例的方法:

(1)方式一:通过类名访问class

Class cls1=String.class;

(2)通过实例访问getClass对象

String s="abc";
		Class cls2=s.getClass();

(3) 通过Class类的静态方法forName(类名)

Class cls3=Class.forName("java.lang.String");

4.2Class实例获取基本信息

Class cls=String.class;
System.out.println("类、接口的名称:"+cls.getName());
System.out.println("完全限定名:"+cls.getSimpleName());
System.out.println("类型名称:"+cls.getTypeName());
//包
Package p=cls.getPackage();
if(p!=null) {
			System.out.println("类所在的包名:"+p);
}

获取父类

Class superClass=String.class.getClass();
System.out.println("父类:"+superClass.getName());

 如果该类没有父类则获取的值为null

如果一个类实现了一个接口,它不仅可以实现接口中的抽象方法,还可以继承默认方法 

4.3判断类型

Class cls=String.class;
System.out.println("是否为接口:"+cls.isInterface());
System.out.println("是否为数组"+cls.isArray());
System.out.println("是否为枚举类型:"+cls.isEnum());

4.4创建实例对象

Class cls=Class.forName("s07_11.Order");
Object obj1=cls.newInstance();

5.常用方法

5.1获取构造方法

获取所有公有构造方法(包含父类)

Constructor[] constructors=cls.getConstructors();
		for(Constructor con:constructors) {
			System.out.println(con);
		}

获取所有的构造方法(不包含父类)

Constructor[] constructors2=cls.getDeclaredConstructors();
		for (Constructor constructor2 : constructors2) {
			System.out.println(constructor2);
		}

获取一个构造方法

Constructor constructor=cls.getDeclaredConstructor(String.class);

获取有参数的有参构造方法(参数的类型填写顺序必须和有参构造中参数的顺序一致)

Constructor constructor=cls.getDeclaredConstructor(String.class);

调用有参构造方法创建实例

在调用私有的有参构造方法要设置constructor.setAccessible(true)

Example ex=(Example)constructor.newInstance("aaa");

5.2访问字段(成员变量)

获取公有的字段·

Field [] fields=cls.getFields();

获取所有定义的字段(不包含父类)


	    Field[] fields=cls.getDeclaredFields();
		for(Field f:fields) {
			System.out.println("成员变量访问修饰符(int):"+f.getModifiers());
			System.out.println("成员变量访问修饰符:"+Modifier.toString(f.getModifiers()));
			System.out.println("成员变量类型:"+f.getType());
			System.out.println("成员变量名:"+f.getName());
			System.out.println();
	}

使用反射完成成员变量保存值

Class cls=Book.class;//获取Class类型对象
		Object obj=cls.newInstance();//通过反射创建Book类的对象
		//按照字段名称,获取指定字段
		Field field1=cls.getField("bookName");
		//参数1:目标Book对象
		//参数2:存入成员变量中的值
		field1.set(obj, "平凡的世界");
        //bookId是私有的
		Field field2=cls.getDeclaredField("bookId");
		field2.setAccessible(true);
		field2.setInt(obj, 1);

5.3获取所有的方法

获取所有的public方法(包含父类)

Method[] methods=cls.getMethods();

获取所有的方法(不包含父类)

Method[] methods=cls.getDeclaredMethods();
	for(Method m:methods) {
			System.out.println("方法的修饰符类型:"+Modifier.toString(m.getModifiers()));
			System.out.println("方法的返回值类型:"+m.getReturnType());
			System.out.println("方法的名称:"+m.getName());

5.4获取参数类型

获取所有参数类型

Class[] parameterTypes=m.getParameterTypes();

获取所有参数对象

Parameter[] paarameter=m.getParameters();
			for(Parameter p:paarameter) {
				System.out.println(p.getName());
				System.out.println(p.getType());
				System.out.println("---------------------------");
			}

 按照方法名称和参数类型获取Method对象


		Class cls=Book.class;
		Object obj=cls.newInstance();
		//Method对象的invoke作用
		//以反射的方式执行create方法
		Method method=cls.getMethod("dosth",int.class,double.class);
		int r=(int)method.invoke(obj, 1,2);
		System.out.println(r);

5.5调用静态方法

Class cls=Math.class;
Method method=cls.getMethod("log10", double.class);
int size=Double.valueOf((double)method.invoke(null, 12345)).intValue()+1;
System.out.println(size);

6.多态问题

创建一个Person对象,并定义hello()方法,Student类继承了Person类并重写了hello方法,那么Person.class获取的Method作用于Student调用的是那个类的hello方法呢? 调用的是Student的hello方法

public class Demo05 {
	public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Method  m=Person.class.getMethod("hello") ;
		m.invoke(new Student());
	}

}		
class Person{
	public void hello() {
		System.out.println("Person.hello");
	}
}
class Student extends Person{
	public void hello() {
		System.out.println("Student.hello");
	}
}

该代码的执行过程相当于(父类的引用指向子类实例)

Person p=new Student();

p.hello()

通过反射调用方法时任然遵循多态原则。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值