Java基础之反射

说反射先来聊聊Java中创建对象大概有这几种方式:

1、使用new关键字:这是我们最常见的也是最简单的创建对象的方式

2、使用Clone的方法:无论何时我们调用一个对象的clone方法,JVM就会创建一个新的对象,将前面的对象的内容全部拷贝进去

3、使用反序列化:当我们序列化和反序列化一个对象,JVM会给我们创建一个单独的对象

上边是Java中常见的创建对象的三种方式,其实除了上边的三种还有另外一种方式,就是接下来我们要讨论的 “反射”
什么是反射

反射就是把Java类中的各个组成部分进行解剖,并映射成一个个的Java对象,拿到这些对象后可以做一些事情。

既然说反射是解剖Java类中的各个组成部分,所以说咱们得知道一个类中有哪些部分?

例如,一个类有:构造方法,方法,成员变量(字段),等信息,利用反射技术咱们可以把这些组成部分映射成一个个对象

拿到映射后的构造方法,可以用它来生成对象;拿到映射后的方法,可以调用它来执行对应的方法;拿到映射后的字段,可以用它来获取或改变对应字段的值;

反射能干什么

说完反射的概念后,咱们说一下反射能干什么?

一般来说反射是用来做框架的,或者说可以做一些抽象度比较高的底层代码,反射在日常的开发中用到的不多,但是咱们还必须搞懂它,因为搞懂了反射以后,可以帮助咱们理解框架的一些原理。所以说有一句很经典的话:反射是框架设计的灵魂。现在说完这个可能还不太能理解,不急,等下说完一个快速入门的例子后,应该会稍微有点感觉

怎么得到想反射的类

首先大家要明白一点,咱们写的代码是存储在后缀名是 .java的文件里的,但是它会被编译,最终真正去执行的是编译后的 .class文件。Java是面向对象的语言,一切皆对象,所以java认为 这些编译后的 class文件,这种事物也是一种对象,它也给抽象成了一种类,这个类就是Class,大家可以去AIP里看一下这个类

看API文档后,有一个方法forName(String className); 而且是一个静态的方法,这样咱们就可以得到想反射的类了

 

2、解剖类
我们知道一个类里一般有构造函数、方法、成员变量(字段/属性)这三部分组成

翻阅API文档,可以看到

Class对象提供了如下常用方法:

public Constructor getConstructor(Class<?>…parameterTypes)

public Method getMethod(String name,Class<?>… parameterTypes)

public Field getField(String name)

public Constructor getDeclaredConstructor(Class<?>…parameterTypes)

public Method getDeclaredMethod(String name,Class<?>… parameterTypes)

public Field getDeclaredField(String name)

这些方法分别用于帮咱们从类中解剖出构造函数、方法和成员变量(属性)。

然后把解剖出来的部分,分别用Constructor、Method、Field对象表示。
反射“一个参数”的构造函数

package com.hqyj.test;
/**
 * 
 * @author Botlanguage
 *
 */
public class Person {
	private String name;
	private int age;
	private  double height;
	public Person(int age) {
		
		System.out.println("年龄:" + age);
	}
	public Person(String name, int age) {
		
		System.out.println("姓名:" + name + "年龄" + age);
	}

	public Person() {
		System.out.println("这是一个无参构造函数");
	}
	
}
package com.hqyj.test;

import java.lang.reflect.Constructor;
/**
 * 
 * @author Botlanguage
 *
 */
public class Fanshe {
	//反射无参的构造函数
	public void test() throws Exception {
		Class classz = Class.forName("com.hqyj.test.Person");
		Constructor c = classz.getConstructor(null);
		c.newInstance(null);
	}

}
package com.hqyj.test;
/**
 * 
 * @author Botlanguage
 *
 */
public class Test {
	public static void main(String[] args) throws Exception {
		Fanshe f = new Fanshe();
		f.test();
	}
}

运行结果:

 反射“多个参数”的构造函数

package com.hqyj.test;

import java.lang.reflect.Constructor;
/**
 * 
 * @author Botlanguage
 *
 */
public class Fanshe {
	//反射无参或多个构造函数
	public void test() throws Exception {
		Class classz = Class.forName("com.hqyj.test.Person");
//		Constructor c = classz.getConstructor(null);//无参
//		Constructor c = classz.getConstructor(String.class);//一个\
		Constructor c = classz.getConstructor(String.class,int.class);
		c.newInstance("Botlanguage",23);
	}

}

 读取私有的属性

package com.hqyj.test;

import java.lang.reflect.Constructor;
import java.util.Set;
/**
 * 
 * @author Botlanguage
 *
 */
public class Fanshe {
	//反射无参或多个构造函数
	public void test() throws Exception {
		Class classz = Class.forName("com.hqyj.test.Person");
//		Constructor c = classz.getConstructor(null);//无参
//		Constructor c = classz.getConstructor(String.class);//一个\
//		Constructor c = classz.getConstructor(String.class,int.class);
		Constructor c = classz.getDeclaredConstructor(int.class); //读取私有的
//		c.newInstance("Botlanguage",23);
		c.setAccessible(true);//暴力反射
		c.newInstance(23);

运行结果:

注意:在反射私有的构造函数时,用普通的clazz.getConstructor()会报错,因为它是私有的,所以提供了专门反射私有构造函数的方法 clazz.getDeclaredConstructor(int.class);//读取私有的构造函数,用这个方法读取完还需要设置一下暴力反射才可以
如何得到对象所有的构造函数:
 

 截下来我们获取它的方法:

请看下集

评论区可以谈谈你们对反射的了解✌

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值