java 反射机制

java 反射简介

java反射机制在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。

反射的作用

在开发过程中,有时我们会遇到某个类的某个成员变量、方法或是属性是私有的或是只对系统应用开放,这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法。

与java反射相关的类
类名作用
Constructor类的构造方法
Class表示类的实体,在运行的java程序中代表类或接口
Field代表类的属性
Method代表类的方法
Calss类
  • 获取类相关的方法
方法名作用
asSubclass(Class<?> clazz)把传递的类的对象转换成代表其子类的对象
Cast把对象转换成代表类或是接口的对象
getClassLoader()获取类加载器
getClasses()返回一个数组,数组中包含该类中所有公共类和接口类的对象
getDeclaredClasses()返回一个数组,数组中包含该类中所有类和接口类的对象
forName(String className)根据类名返回类的对象
getName()获得类的完整路径名字
newInstance()获取类的对象实例
getPackage()获取包名
getSimpleName获取类的全路径
getSuperclass获取类当前继承的父类的名字
  • 获取类中属性的相关方法
方法名作用
getField(String name)获得某个公有的属性对象
getFields获得所有公有的属性对象
getDeclaredFields(String name)获得某个属性对象
getDeclaredFields()获得所有属性对象
  • 获取类中相关注解的方法
方法名作用
getAnnotation(Class<?> annotationClass)返回该类中与参数类型匹配的公有注解对象
getAnnotations()返回该类所有的公有注解对象
getDeclaredAnnotation(Class<?> annotationClass)返回该类中与参数类型匹配的所有注解对象
getDeclaredAnnotations()返回该类所有的注解对象
  • 获取类中构造器的相关方法
方法名作用
getConstructor(Class…<?> parameterTypes)获得该类中参数类型匹配的公有构造方法
getConstructors()获得该类中所有的共有构造方法
getDeclaredConstructor(Class…<?> paramterTypes)获得类中与参数匹配的构造方法
getDeclaredConstructors()获得类中所有的构造方法
  • 获取类中方法的相关方法
方法名作用
getMethod(String name,Class…<?> parameterTypes)获取某个类中的公有方法
getMethods()获取该类所有的公有方法
getDeclaredMethod(String name,Class…<?> parametersType)获取该类中的某个方法
getDeclaredMethods()获取该类中所有方法
  • 其它的一些方法
方法名作用
isAnnotation()如果是注解类型返回true
isAnnotationPresent(Class<? extends Annotation> annotationClass)如果是指定类型注解类型则返回true
isAnonymousClass如果是匿名类则返回true
isArray()如果是一个数组则返回true
isEnum如果是枚举则返回true
isInstance(Object obj)如果obj是该类的实例则返回true
isInterface()如果是接口类则返回true
isLocalClass如果是局部类则返回true
isMemberClass如果是内部类则返回true
Field
  • Field代表类的属性
方法名作用
set(Object obj,Object value)为某个字段赋值,参数1为该属性所在类的实例,参数2则是该属性的属性值
get(Object obj)获取Object对应的属性值
equals(Object obj)属性相等则返回true
Constructor
  • Constructor代表类的构造方法
方法名作用
newInstance(Object obj…)创建类的对象实例并为属性赋值
获取Class对象的三种方式

1.调用某个类的class属性获取Class对象,如Student.class会返回Person类对应的Class对象(其实就是得到一个类的一份字节码文件);

2、使用Class类的forName(String className)静态方法,className表示全限定名;如String的全限定名:java.lang.String;

3、调用某个对象的getClass()方法。该方法属于Object类;

Student类

package com.xlq.reflect01;

public class Student {
	private String name;
    private int age;
	
	public String getName() {
		return name;
	}
 
	public void setName(String name) {
		this.name = name;
	}
 
	public int getAge() {
		return age;
	}
 
	public void setAge(int age) {
		this.age = age;
	}
	
	public Student() {
    }
	private Student(int age) {
		this.age=age;
	}
	private Student(String name) {
		this.name=name;
	}
	public Student(String name, int age) {
		this.age=age;
		this.name=name;
	}
	private void show(String name){
		System.out.println("这是一个私有方法"+name);
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}	
}

package com.xlq.reflect01;

public class ReflectTest01 {
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
		Class<?> s1=null;
		Class<?> s2=null;
		Class<?> s3=null; 
		//1 直接通过类名.Class的方式得到 
		s1=Student.class;
		//2 通过全类名获取,用的比较多,但可能抛出ClassNotFoundException异常
		s2=Class.forName("com.xlq.reflect01.Student");
		//3 通过对象的getClass()方法获取,这个使用的少(一般是传的是Object,不知道是什么类型的时候才用)
		Object o=new Student();
		s3=o.getClass();
		System.out.println(s1);
		System.out.println(s2);
		System.out.println(s3);	
	}
}

测试结果

class com.xlq.reflect01.Student	
class com.xlq.reflect01.Student	
class com.xlq.reflect01.Student
利用newInstance创建对象

      利用Class类的newInstance方法创建实例,实际上就是调用了类的无参构造方法,一旦类没有无参构造方法(创建了带参数的构造方法),就会出现异常,所以在创建类的时候一般都会将无参的构造方法声明出来

package com.xlq.reflect01;

public class ReflectTest05 {
	public static void main(String[] args) throws InstantiationException, IllegalAccessException {
		Class<?> s=null;
		try {
			s = Class.forName("com.xlq.reflect01.Student");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		Object o=s.newInstance();
		if(o instanceof Student){
			System.out.println(true);
		}else{
			System.out.println(false);
		}
		System.out.println(o);
	}
}
true
Student [name=null, age=0]

这里我将Student类的无参构造注释掉之后在运行程序
在这里插入图片描述

利用反射机制获取类中的构造方法 Constructor
package com.xlq.reflect01;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;

public class ReflectTest02 {
	public static void main(String[] args){
		Class<?> s=null;
		try {
			s = Class.forName("com.xlq.reflect01.Student");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		//获取全部的构造函数
		Constructor<?>[] cons=s.getDeclaredConstructors();
		for (int i=0;i<cons.length;i++){
			System.out.print("构造函数的类型: "+Modifier.toString(cons[i].getModifiers())+"  ");
			//获取构造函数的参数类型
			Class<?>[] parametertypes = cons[i].getParameterTypes();
			for (int j = 0; j < parametertypes.length; j++) {
	             System.out.print("参数的类型: "parametertypes[j].getName() + "   ");
			}
			System.out.println();
		}
	}
}

在这里插入图片描述

利用反射获取类中的私有属性并赋值 Field
public static void main(String[] args) {
		Class<?> s=null;
		try {
			s = Class.forName("com.xlq.reflect01.Student");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		try {
			//得到类的实例
			Object o =s.newInstance();
			//获取类的私有字段并为字段赋值
			Field field =s.getDeclaredField("name");
			Field field1=s.getDeclaredField("age");
			field.setAccessible(true);
			field1.setAccessible(true);
			//为私有字段赋值
			field.set(o, "张三");
			field1.set(o, 18);
			System.out.println(o);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
Student [name=张三, age=18]
利用反射获取类中的方法 Method
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
		Class<?> s=null;
		try {
			s = Class.forName("com.xlq.reflect01.Student");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		//获取所有修饰权限的方法
		Method []methods1=s.getDeclaredMethods();
		//不能获取private/protected/default方法
		Method []methods2=s.getMethods();
		for (Method method : methods1) {
			System.out.println(method);
		}
		System.out.println("---------------------------------");
		for (Method method : methods2) {
			System.out.println(method);
		}
	}
public java.lang.String com.xlq.reflect01.Student.toString()
public java.lang.String com.xlq.reflect01.Student.getName()
public void com.xlq.reflect01.Student.setName(java.lang.String)
public int com.xlq.reflect01.Student.getAge()
private void com.xlq.reflect01.Student.show(java.lang.String)
public void com.xlq.reflect01.Student.setAge(int)
-----------------
public java.lang.String com.xlq.reflect01.Student.toString()
public java.lang.String com.xlq.reflect01.Student.getName()
public void com.xlq.reflect01.Student.setName(java.lang.String)
public int com.xlq.reflect01.Student.getAge()
public void com.xlq.reflect01.Student.setAge(int)
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 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()

在这里插入图片描述

利用反射获取类中指定的私有方法 Method
public static void main(String[] args) {
		Class<?> s=null;
		try {
			s = Class.forName("com.xlq.reflect01.Student");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		Class<?>[] p2={String.class};//类中普通的私有方法
		try {
			//得到类的实例
			Object o =s.newInstance();
			//getDeclaredMethod方法获取到这个私有方法,第一个参数是方法名,第二个参数是参数类型
			Method method = s.getDeclaredMethod("show",p2);
			method.setAccessible(true);
			Object []params={"方法名是show"};
			//两个参数一个是类的实例,一个是方法参数
			method.invoke(o, params);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
这是一个私有方法方法名是show
利用反射获取注解

https://www.cnblogs.com/a591378955/p/8350499.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值