java反射机制(条例清晰,适合初学者)

####1、java反射机制简介

  • 定义:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
  • 理解:java源文件编译成字节码文件时,都会创建一个Class类对象,Class类的实例化对象代表一个正在运行的Java类或接口,也就是通过class对象就可以动态地获取类或者对象的相关信息。同时java反射,就是把类的属性和方法反射成一个个对象,Class对象可以获得类的成员信息,Constructor对象可以获得类的构造方法,Method对象可以获得类的方法,Field对象可以获得类的属性。

####2、获取Class类对象的三种方式
######(1)通过类的全限定名(包+类名)
这里写图片描述
Class clazz = Class.forName(“entity.People”);
######(2)通过类本身的.class属性
Class clazz = People.class;
######(3)通过对象获取
People people = new People();
Class clazz = people.getClass();
####3、反射获取构造方法
People类

package entity;
public class People {
	//构造方法
	public People() {
	    System.out.println("公共的无参构造方法");
	}
	People(int age) {
		System.out.println("默认的带一个参数的构造方法");
	}
	protected People(String name) {
		System.out.println("受保护的带一个参数的构造方法");
	}
	private People(int age,String name) {
		System.err.println("私有的带两个参数的构造方法");
	}
}

测试类Test01

import java.lang.reflect.Constructor;
import entity.People;
/**
 * 测试构造方法
 * @author limingxing
 */
public class Test01 {
	public static void main(String[] args) throws Exception {
		//得到Class类对象
		Class clazz = Class.forName("entity.People");
		System.out.println(".....getConstructors()获取的是public修饰的构造方法.....");
		Constructor[] cons = clazz.getConstructors();
		for(Constructor con:cons) {
			System.out.println(con);
		}
		System.out.println("......getDeclaredConstructors()获取public、默认的、protected、private修饰的方法......");
		Constructor[] cons2 = clazz.getDeclaredConstructors();
		for(Constructor con :cons2) {
			System.out.println(con);
		}
		System.out.println(".....获得指定参数的构造方法...............");
		//这里用getDeclaredConstructor("类型.class","...")去获取
		Constructor con3 = clazz.getDeclaredConstructor(int.class);
		System.out.println(con3);
		System.out.println("........使用构造方法............");
		Constructor con4 = clazz.getDeclaredConstructor(int.class,String.class);
		con4.setAccessible(true);
		People people = (People)con4.newInstance(20,"libai");
		System.out.println(people);
	}
}

结果:

.....getConstructors()获取的是public修饰的构造方法.....
public entity.People()
......getDeclaredConstructors()获取public、默认的、protected、private修饰的方法......
private entity.People(int,java.lang.String)
protected entity.People(java.lang.String)
entity.People(int)
public entity.People()
.....获得指定参数的构造方法...............
entity.People(int)
........使用构造方法............
entity.People@7852e922
私有的带两个参数的构造方法

####4、反射获得成员变量
People2类

package entity;
/**
 * People2类
 * @author limingxing
 *
 */
public class People2 {
	public int pid;
    int age;
    protected String job;
	private String name;
	//可以得到私有的值
	public String getName() {
		return name;
	}
}

测试类Test02

import entity.People2;
/**
 * 
 * @author limingxing
 *
 */
public class Test02 {
	public static void main(String[] args) throws Exception{
		Class clazz = Class.forName("entity.People2");
		System.out.println(".....获得public修饰的变量........");
		Field[] fields = clazz.getFields();
		for(Field f:fields) {
			System.out.println(f);
		}
		System.out.println("....获得public、默认的、protected、private修饰的变量.......");
		Field[] fields2 = clazz.getDeclaredFields();
		for(Field f:fields2) {
			System.out.println(f);
		}
		System.out.println("....获得指定变量名变量.......");
		//public修饰的可以用getField()来获取
		Field field3 = clazz.getDeclaredField("age");
		System.out.println(field3);
		System.out.println(".......调用变量.............");
		Field fname = clazz.getDeclaredField("name");
		System.out.println(fname);
		People2 people = (People2) clazz.newInstance();
		fname.setAccessible(true);//要是获取非私有的,就不用设置访问权限。
		fname.set(people, "libai");
		System.out.println(people.getName());
	}
}

结果:

.....获得public修饰的变量........
public int entity.People2.pid
....获得public、默认的、protected、private修饰的变量.......
public int entity.People2.pid
int entity.People2.age
protected java.lang.String entity.People2.job
private java.lang.String entity.People2.name
....获得指定变量名变量.......
int entity.People2.age
.......调用变量.............
private java.lang.String entity.People2.name
libai

####5、反射获取成员方法
People03类

package entity;
/**
 * 
 * @author limingxing
 *
 */
public class People03 {
	
	public void say() {
		System.out.println("调用无参的say1方法");
	}
	
    void say2(int age) {
    	System.out.println("调用一个int类型参数say2方法");
    }
    
    protected void say3(String name) {
    	System.out.println("调用一个String类型参数的say3方法");
    }
    
    private void say4(int age,String name) {
    	System.out.println("调用int类型和String类型参数的say4方法");
    }
}

测试类Test03

package test;

import java.lang.reflect.Method;

import entity.People03;

public class Test03 {
	public static void main(String[] args) throws Exception{
		Class<?> clazz = Class.forName("entity.People03");
		System.out.println(".....获取public修饰的成员方法......");
		//包括继承父类的public方法
		Method[] methods = clazz.getMethods();
		for(Method m:methods) {
			System.out.println(m);
		}
		System.out.println("....获取public、默认的、protected、private成员方法....");
		Method[] methods2 = clazz.getDeclaredMethods();
		for(Method m:methods2) {
			System.out.println(m);
		}
		System.out.println("....获得指定名称的成员方法.......");
		Method method = clazz.getDeclaredMethod("say3", String.class);
		System.out.println(method);
		System.out.println(".....调用成员方法......");
		//私有方法都要将访问权限改为true,才能执行该方法。
		Method method2 = clazz.getDeclaredMethod("say4", int.class,String.class);
		//不管是方法,还是属性,都离不开对象,所有这里也要创建一个对象。
		People03 people = (People03) clazz.newInstance();
		method2.setAccessible(true);
		method2.invoke(people, 20,"zhangsan");
	}
}

结果:

.....获取public修饰的成员方法......
public void entity.People03.say()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
....获取public、默认的、protected、private成员方法....
private void entity.People03.say4(int,java.lang.String)
void entity.People03.say2(int)
public void entity.People03.say()
protected void entity.People03.say3(java.lang.String)
....获得指定名称的成员方法.......
protected void entity.People03.say3(java.lang.String)
.....调用成员方法......
调用int类型和String类型参数的say4方法

####6、创建具体对象的两种方式
这里写图片描述
前提先得到Class类对象clazz(自己取的名字)
######(1)Class类对象.newInstance()
People people = (People)clazz.newInstance();
######(2)Class.类对象.getConstructor().newInstance(),当然构造方法也可以带参的。
People people =(People)clazz.getConstructor().newInstance();
####7、反射的优缺点
参见别人的博客:(https://blog.csdn.net/Elias94/article/details/80361035)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值