java反射学习(适合新人)

有很多面试的同学整天背那些官方并且浅薄的面试答案,而不知道其的原理,或则说根本就不知道具体的作用,所以呢,小子不才,就准备做一个课程系列,针对于各大面试题,来一个概括性的讲述,虽然不是特别具体,但是用来面试完全足够了。
今天我们首先来学习反射!

1,什么是反射?

官方回答:就是运行状态下,动态获取这个类的所有信息!

2,反射的作用?

1,反编译
2,通过反射机制访问java对象的属性,方法,构造方法

3,应用场景

1,JDBC的加载驱动(重点!)
2,SpringIOC (下一篇文章我会实际的讲一下,springIOC的源码)
3,框架
几乎所有框架都用到了反射。

4,反射的实现代码!

1,使用无参构造方法实现

1.创建实体类

package entity;

public class UserEntity {
	private String uid;
	private String uname;
	public UserEntity(){
		System.out.println("这是一个无参构造函数!");
	}

	public UserEntity(String name){
		System.out.println("这是一个有参构造函数!参数:"+name);
	}
	public String getUid() {
		return uid;
	}
	public void setUid(String uid) {
		this.uid = uid;
	}
	public String getUname() {
		return uname;
	}
	public void setUname(String uname) {
		this.uname = uname;
	}
}

2.使用反射创建实体类,并且对成员进行赋值

package test;
import entity.UserEntity;
/**
* 项目名称:WorkReflect  
* 类描述:("反射")
* 创建人:莫参商 
* 创建时间:2020-1-7 上午10:54:09  
* 修改人:acer     
* @version   
*   
 */
public class ReflectTest {
	
	public static void main(String[] args) throws Exception {
		//1,获取类的字节码文件,必须使用完整路径
		Class<?> forName = Class.forName("entity.UserEntity");
		//2, 创建对象,类似于new;newInstance是使用的无参构造;
		Object obj = forName.newInstance();
		//3,这个时候对象就被创建出来了,然后转化类型,让他显示出来
		UserEntity user = (UserEntity) obj;
		System.out.println(user);
		user.setUname("莫参商");
		System.out.println(user.getUname());
	}
}

运行结果:
在这里插入图片描述
在这里补充一个知识,newInstance创建一个对象,会自动调用这个对象构造函数。
使用new创建对象的本质其实也是调用了 newInstance方法。
下面出一道理论面试题;

下面的对象创建方法中哪些会调用构造方法 ()?
A. new语句创建对象
B. 调用Java.io.ObjectInputStream的readObject方法
C. java反射机制使用java.lang.Class或java.lang.reflect.Constructor的newInstance()方法
D. 调用对象的clone()方法

解释一下;A:构造方法new
B:序列化对象
C:反射
D:克隆
在这里只有 A和C会调用构造方法

2,创建有参构造方法实现

  1. 创建实体类,同上
  2. 使用反射技术创建对象,并且赋值
package test;

import java.lang.reflect.Constructor;

import entity.UserEntity;

/**
* 项目名称:WorkReflect  
* 类描述:("反射")
* 创建人:莫参商 
* 创建时间:2020-1-7 上午10:54:09  
* 修改人:acer     
* @version   
*   
 */

public class ReflectTest {
	
	public static void main(String[] args) throws Exception {
		//1,获取类的字节码文件,必须使用完整路径
		Class<?> forName = Class.forName("entity.UserEntity");
		//使用有参构造
		Constructor<?> constructor = forName.getConstructor(String.class);
		//创建对象
		Object newInstance = constructor.newInstance("莫参商");
		UserEntity user = (UserEntity) newInstance;
		System.out.println(user);
		user.setUname("莫参商");
		System.out.println(user.getUname());
	}
}

结果
在这里插入图片描述
3,使用反射技术,调用类里面的方法
1.在类中添加方法,这次为了方便,我就在实体类中添加方法了。

//普通方法
	public String test(String name){
		System.out.println("这是一个普通有返回值,有参数的方法!参数是:"+name);
		return name;
	}
	//私有方法
	private String test01(String name){
		System.out.println("这是一个普通有返回值,有参数的方法!参数是:"+name);
		return name;
	}
  1. 使用反射技术,调用方法
package test;

import java.lang.reflect.Constructor;

import entity.UserEntity;

/**
* 项目名称:WorkReflect  
* 类描述:("反射")
* 创建人:莫参商 
* 创建时间:2020-1-7 上午10:54:09  
* 修改人:acer     
* @version   
*   
 */

public class ReflectTest {
	
	public static void main(String[] args) throws Exception {
		//1,获取类的字节码文件,必须使用完整路径
		Class<?> forName = Class.forName("entity.UserEntity");
		Object obj = forName.newInstance();
		UserEntity user = (UserEntity) obj;
		user.test("莫参商");
	}
}

结果:
在这里插入图片描述
我们在类中定义了两个方法,一个是普通的,一个是私有的。
我们知道私有方法不能被其他的类访问,用以往的方法肯定是不能访问的。

4.暴力反射,强行访问类中的私有方法

package test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import entity.UserEntity;

/**
* 项目名称:WorkReflect  
* 类描述:("反射")
* 创建人:莫参商 
* 创建时间:2020-1-7 上午10:54:09  
* 修改人:acer     
* @version   
*   
 */

public class ReflectTest {
	
	public static void main(String[] args) throws Exception {
		//1,获取类的字节码文件,必须使用完整路径
		Class<?> forName = Class.forName("entity.UserEntity");
		
		//2 实例化对象
        Object obj = forName.newInstance();
        //3 暴力获得私有方法
		Method mt = forName.getDeclaredMethod("test01", String.class);
		//4 暴力访问
		mt.setAccessible(true);
		//5 使用test01方法
		Object invoke = mt.invoke(obj, "莫参商");
		System.out.println(invoke);

		
	}

}

结果:
在这里插入图片描述

发布了7 篇原创文章 · 获赞 7 · 访问量 211

猜你喜欢

转载自blog.csdn.net/qq_41566219/article/details/103869927