java反射之详解


在这里插入图片描述

1.什么是反射?

1.在Java中,反射是指程序在运行时可以观察和修改自己的行为的能力。反射使得程序可以动态地获取类型信息、访问对象的属性和方法,并调用方法,而不需要提前在代码中编写对应的静态类型和调用代码。借助反射,程序可以在运行时动态地加载和使用类,而不需要在编译时知道有哪些类存在。反射常用于框架开发、插件化和动态代理等场景。在Java中,反射API包括java.lang.reflect包中的类和接口,这些API允许程序获取类型信息、构造类实例、访问和修改字段和方法等。

2. 反射中类类的含义与概念

1.前言

Java反射机制提供了一组API,用于在运行时检查、访问和修改类、接口、字段、方法和构造函数的信息。Java反射API包括在java.lang.reflect包中定义的一些接口和类,这些接口和类提供了以下功能:

1.Class类:

Class类是Java反射的核心类,它用于表示一个类或接口的类型信息。通过Class类,可以获取一个类的所有元素信息,包括字段、方法、构造函数、父类和实现的接口等。

2.Constructor类

Constructor类:Constructor类提供了对类的构造函数的访问和调用。它允许我们使用类的构造函数创建对象实例,并提供了对构造函数参数的访问。

3.Method类

Method类:Method类提供了对方法的访问和调用。它允许我们在运行时执行类中定义的方法,并提供了对方法参数和返回值的访问。

4.Field类

Field类:Field类提供了对字段的访问和修改。它允许我们获取或设置类的成员变量的值。

5.Modifier类

Modifier类:Modifier类用于获取和修改字段、方法和类的修饰符,例如public、private、static等。

使用Java反射机制,程序可以在运行时动态获取和修改类、接口、字段和方法等的信息,从而使得代码更加灵活和扩展性更强,在某些场景下比静态编码更有优势。反射虽然功能强大,但也会带来性能损失和安全问题,因此在使用反射时需要谨慎权衡利弊。
1.示例
接下来,会以下面student类,为示例进行各种演示,助力你们理解,反射。

package com.niyin.reflection;

public class Student {
	private String sid;

	private String sname;

	public Integer age;
	
	static{
		System.out.println("加载进jvm中!");
	}

	public Student() {
		super();
		System.out.println("调用无参构造方法创建了一个学生对象");
	}

	public Student(String sid) {
		super();
		this.sid = sid;
		System.out.println("调用带一个参数的构造方法创建了一个学生对象");
	}

	public Student(String sid, String sname) {
		super();
		this.sid = sid;
		this.sname = sname;
		System.out.println("调用带二个参数的构造方法创建了一个学生对象");
	}

	@SuppressWarnings("unused")
	private Student(Integer age) {
		System.out.println("调用Student类私有的构造方法创建一个学生对象");
		this.age = age;
	}

	public String getSid() {
		return sid;
	}

	public void setSid(String sid) {
		this.sid = sid;
	}

	public String getSname() {
		return sname;
	}

	public void setSname(String sname) {
		this.sname = sname;
	}

	public void hello() {
		System.out.println("你好!我是" + this.sname);
	}

	public void hello(String name) {
		System.out.println(name + "你好!我是" + this.sname);
	}

	@SuppressWarnings("unused")
	private Integer add(Integer a, Integer b) {
		return new Integer(a.intValue() + b.intValue());
	}
}

3.反射实例化,Constructor

1.调用无参构造方法

package com.niyin.reflection;

import java.lang.reflect.Constructor;

/**
 * 
 * @author 匿瘾
 *
 */
public class Demo1 {
public static void main(String[] args) throws Exception {

	Class c  = Class.forName("com.niyin.reflection.Student");
	Student s1 = (Student) c.newInstance();
	System.out.println(s1);


}
	
}

运行结果
在这里插入图片描述

2.调用一个参数的

package com.niyin.reflection;

import java.lang.reflect.Constructor;

/**
 * 
 * @author 匿瘾
 *
 */
public class Demo1 {
public static void main(String[] args) throws Exception {

	Class c  = Class.forName("com.niyin.reflection.Student");

//	System.out.println(s1);
	//调用有一个参数的,的方法
	Constructor cr1=c.getConstructor(String.class);
//	
Student s2 = (Student) cr1.newInstance("s001");
	
System.out.println(s2);

}
	
}

运行结果
在这里插入图片描述

3.调用两个参数的

package com.niyin.reflection;

import java.lang.reflect.Constructor;

/**
 * 
 * @author 匿瘾
 *
 */
public class Demo1 {
public static void main(String[] args) throws Exception {

	Class c  = Class.forName("com.niyin.reflection.Student");
	Student s1 = (Student) c.newInstance();

	Constructor cr2=c.getConstructor(String.class,String.class);
	Student s3 = (Student) cr2.newInstance("s002","nb");
	 System.out.println(s3);

}
	
}

运行结果
在这里插入图片描述

4.调用私有化的

package com.niyin.reflection;

import java.lang.reflect.Constructor;

/**
 * 
 * @author 匿瘾
 *
 */
public class Demo1 {
public static void main(String[] args) throws Exception {

	Class c  = Class.forName("com.niyin.reflection.Student");
	Student s1 = (Student) c.newInstance();

	 
		Constructor cr3=c.getDeclaredConstructor(Integer.class);
		cr3.setAccessible(true);
		Student s4=(Student) cr3.newInstance(18);
	 System.out.println(s4);
}
	
}

运行结果
在这里插入图片描述
想要调用私有,主要是通过 cr3.setAccessible(true);
打开权限。

4.反射方法的调用,Method

1.前言

1.method介绍
两个参数,name:方法名,parameterTypers:调用方法所需要传的类型

2.invoked介绍
两个参数
obj:类实例
args:参数值
invoke()方法的返回值是该方法的返回值,如果该方法是void类型,则返回null。

1.调用无参构造方法

package com.niyin.reflection;

import java.lang.reflect.Method;

public class Demo2 {
	public static void main(String[] args) throws Exception {
		Class c = Student.class;
		Student stu = (Student) c.newInstance();
		Method m1 = c.getMethod("hello");
		Object invoke = m1.invoke(stu);
		 System.out.println(invoke);

	}
}

运行结果
在这里插入图片描述

2.调用一个参数的方法

package com.niyin.reflection;

import java.lang.reflect.Method;

public class Demo2 {
	public static void main(String[] args) throws Exception {
		Class c = Student.class;
		Student stu = (Student) c.newInstance();

		Method m2 = c.getMethod("hello", String.class);

		Object invoke1 = m2.invoke(stu, "你好");
		System.out.println(invoke1);
		
	}
}

运行结果

在这里插入图片描述

3.调用私有的方法

package com.niyin.reflection;

import java.lang.reflect.Method;

public class Demo2 {
	public static void main(String[] args) throws Exception {
		Class c = Student.class;
		Student stu = (Student) c.newInstance();

Method m3 	=c.getDeclaredMethod("add", Integer.class,Integer.class);
		
		m3.setAccessible(true);

		Object invoke2 = m3.invoke(stu, 1,2);
		
		System.out.println(invoke2);
		
		
		
	}
}

运行结果
在这里插入图片描述
提升:记得打开m3.setAccessible(true);

5.反射读取属性

1.java中反射读取属性与用get方法获取属性的区别

在Java中,有两种途径可以读取对象的属性:反射和使用getter方法。

反射可以使用Field类来获取实例中的属性值,然后对其进行操作。这种方法的优点是可以直接读取或设置对象的私有属性,并可以根据程序运行时的条件来决定读取哪一个对象的属性。但缺点是反射效率相对较低,而且更容易出错,例如当属性名更改时,编译时不会出现错误,但运行时会因为找不到原先的属性而抛出异常。

而使用getter方法则是通过公共方法来获取属性值,这种方法使用了封装和控制属性访问的思想,可以使代码更加健壮且易于维护。缺点是如果想要读取私有属性,则必须在类中提供相应的public方法,否则无法直接获取。

因此,如果需要对属性进行访问或修改,推荐使用getter方法;如果需要在程序运行时动态地访问属性值或直接访问私有属性,可以使用反射。在实际开发中,需要根据具体的场景来确定应该采用哪种方式。

示例

1.get方法获取

package com.niyin.reflection;

import java.lang.reflect.Field;

public class Demo3 {
public static void main(String[] args) throws Exception{
Class clz	=Student.class;

Student stu =new Student("s001","nv");
System.out.println(stu.getSid()
);
System.out.println(stu.getSname());
	
	
	
	}
	
}

}

运行结果
在这里插入图片描述

2.反射读取属性

package com.niyin.reflection;

import java.lang.reflect.Field;

public class Demo3 {
public static void main(String[] args) throws Exception{
Class clz	=Student.class;

Student stu =new Student("s001","nv");

	
	Field[] declaredFields = clz.getDeclaredFields();
	for (Field f : declaredFields) {
		f.setAccessible(true);
		System.out.println(f.getName()+":" +f.get(stu));
	}
	
}

}

运行结果
在这里插入图片描述
小贴士 :可以根据场景使用
制作不易,希望多多鼓励。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值