JAVA基础-反射

Posted 不愿透露姓名的王建森

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA基础-反射相关的知识,希望对你有一定的参考价值。

反射的基本概念

Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法

Java反射机制提供的功能

  • 在运行时判断任意一个对象所属的类

  • 在运行时构造任意一个类的对象

  • 在运行时判断任意一个类所具有的成员变量和方法

  • 在运行时调用任意一个对象的成员变量和方法

  • 生成动态代理

反射相关的主要API

  • java.lang.Class: 代表一个类

  • java.lang.reflect.Method: 代表类的方法

  • java.lang.reflect.Field: 代表类的成员变量

  • java.lang.reflect.Constructor: 代表类的构造方法

常用的反射方法

  • 前提:若已知具体的类,通过类的class属性获取,该方法
    最为安全可靠,程序性能最高
    实例:Class clazz = String.class;
  • 前提:已知某个类的实例,调用该实例的getClass()方法获
    取Class对象
    实例:Class clazz = “www.kkb.com”.getClass();
  • 前提:已知一个类的全类名,且该类在类路径下,可通过
    Class类的静态方法forName()获取,可能抛出ClassNotFoundException
    实例:Class clazz = Class.forName(“java.lang.String”);

类的加载过程

当程序主动使用某个类时,如果该类还未被加载到内存中,则系统会通过如下三个步骤来对该类进行初始化。

了解ClassLoader

类加载器是用来把类(class)装载进内存的。JVM 规范定义了两种类型的类加载器:启动类加载器(bootstrap)和用户自定 义加载器(user-defined class loader)。 JVM在运行时会产生 3个类加载器组成的初始化加载器层次结构 ,如下图所示

反射的使用

通过Class类来实现:

package day18;

import static org.junit.Assert.*;

import org.junit.Test;

public class PersonTest {

	//没有反射概念之前我们如何使用对象
	@Test
	public void test01() throws Exception {
		Person person = new Person();
		person.name = "zhangsan";
		person.age = 18;
		person.show();
		
		System.out.println(person);
	}
	
	//通过反射,得到我们Person对象
	@Test
	public void test02() throws Exception {
		Class c = Person.class;
		Person person = (Person)c.newInstance();
		person.show();
		System.out.println(person);
	}
	@Test
	public void test03() throws Exception {
		//第一种
		Class c1 = String.class;
		System.out.println(c1.getName());
		Class P1 = Person.class;
		System.out.println(P1.getName());
		//第二种
		Class class1 = "c".getClass();
		System.out.println(class1.getName());
		//第三种
		Class class2 = Class.forName("day18.Person");	
		System.out.println(class2.getName());
		
	}
}
/**
java.lang.String
day18.Person
java.lang.String
day18.Person

*/

难道没有无参的构造器就不能创建对象了吗?

不是!只要在操作的时候明确的调用类中的构造方法,并将参数传递进去

之后,才可以实例化操作。步骤如下:

1)通过Class类的getDeclaredConstructor(Class … parameterTypes) 取得本类的指定形参类型的构造器

2)向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数。

3)通过Constructor实例化对象。

下面我们来举一个例子:

我们的Person类构造如下:

package day18;

public class Person {
	public String name;
	public int age;
	
	public Person() {
	}
    
	public Person(int age,String name) {
		this.name = name;
		this.age = age;
	}
	
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}

	public void show() {
		System.out.println(name +","+ age  );
	}
}

随后我们通过反射的方式,来通过有参构造和无参构造来实现实例化:

	@Test
	public void test04() throws Exception {
		//第一种必须有参数,并且注意构造器权限
		Class class1 = Person.class;
		Person person = (Person)class1.newInstance();
	}
	
	@Test
	public void test05() throws Exception {
        //方法二,使用其他构造方法
		Class class1 = Person.class;
		Constructor c1 = class1.getDeclaredConstructor( int.class  , String.class );
		Person person = (Person)c1.newInstance(18,"Jeason");
		System.out.println(person);
	}


/*
Person [name=Jeason, age=18]
*/

以上是关于JAVA基础-反射的主要内容,如果未能解决你的问题,请参考以下文章

java反射基础

java反射基础知识反射应用实践

Java基础Java反射机制浅解

反射机制

Java基础之反射

反射基础