系列文章目录
java必知必会-java环境搭建
java必知必会-java开发工具安装与使用
java必知必会-java关键字、变量和常量
java必知必会-java数据类型和变量定义
java必知必会-java类和对象
java必知必会-java面向对象的三大特性
java必知必会-java继承与重写、重载
java必知必会-java构造方法与访问修饰符
java必知必会-java抽象类与接口
java必知必会-java常见关键字及其作用
文章目录
前言
本文介绍java中的反射使用
一、什么是反射?
- 在程序的运行状态中,可以构造任意一个类的对象,了解任意一个对象所属的类,了解任意一个类的成员变量和方法,调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为反射机制
- 功能:
- 在运行时构造一个类的对象
- 判断一个类所具有的成员变量和方法
- 调用一个对象的方法
- 生成动态代理
二、反射的优缺点
- 优点:运行期类型的判断,动态加载类,提高代码灵活度
- 缺点:反射相当于解释操作,性能比直接的java代码要慢很多
三、应用场景
- JDBC连接数据库时使用Class.forName()通过反射加载数据库的驱动程序
- Spring通过XML配置反射装载Bean的过程
- Java类里面解析xml或properties里面的内容,得到对应实体类的字节码字符串以及相关的属性信息
- 使用反射机制,根据这个字符串获得某个类的Class实例
- 动态配置实例的属性
- 工厂模式,使用反射机制,根据全限定类名获得某个类的Class实例
四、反射的使用
1. 获得class对象
类名 变量名 = new 类名();Class c1 = 变量名.getClass();
Class c2 = 类名.class;(常用)
Class c3 = Class.forName("完整类名");(常用)
2. 使用class对象获得构造方法
- Constructor getConstructor(Class<?>… parameterTypes);//获得public修饰的构造方法
- Constructor getDeclaredConstructor(Class<?>… parameterTypes);//获得所有构造方法
- Constructor<?>[] getConstructors()(public)//获得所有public修饰构造方法
- Constructor<?>[] getDeclaredConstructors()//获得所有构造方法
public class Main {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class<A> clazz = A.class;
System.out.println("获得public修饰的构造方法");
Constructor<A> constructor = clazz.getConstructor(String.class);
System.out.println(constructor);
System.out.println("获得public修饰的所有构造方法");
Constructor<?>[] constructors = clazz.getConstructors();
for(int i=0;i<constructors.length;i++){
Constructor item = constructors[i];
System.out.println(item);
}
System.out.println("获得包括私有构造方法");
System.out.println(clazz.getDeclaredConstructor(Integer.class,String.class));
System.out.println("获得所有构造方法");
Constructor<?>[] constructors2 = clazz.getDeclaredConstructors();
for(int j=0;j<constructors2.length;j++){
Constructor item2 = constructors[j];
System.out.println(item2);
}
}
}
class A{
private Integer id;
private String name;
private String otherName;
public A(String name){
this.name = name;
}
public A(String name,String otherName){
this.name = name;
this.otherName = otherName;
}
private A(Integer id,String name){
this.id = id;
this.name = name;
}
}
3.根据构造方法创建对象
public class Main {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class<A> clazz = A.class;
Constructor<A> constructorA = clazz.getConstructor(String.class);
//重载构造方法
A a = constructorA.newInstance("a");
a.fun();
Constructor<A> constructorB = clazz.getConstructor();
//默认构造方法
A b = constructorB.newInstance();
b.fun();
}
}
class A{
private String name;
public A(String name){
this.name = name;
}
public A(){
this.name = "default";
}
public void fun(){
System.out.println("my name is " + name);
}
}
3. 使用class对象获得属性
- Field getField(String name);(本类及父类public属性
- Field getDeclaredField() (本类及父类所有public属性
- Field[] getFields() (本类及父类public属性
- Field[] getDeclaredFields() ;(本类所有属性
public class Main {
public static void main(String[] args) throws NoSuchFieldException {
Class<A> clazz = A.class;
System.out.println("获得public修饰的属性");
Field field = clazz.getField("name");
System.out.println(field);
System.out.println("获得public修饰的所有属性");
Field[] fields = clazz.getFields();
for(int i=0;i<fields.length;i++){
Field item = fields[i];
System.out.println(item);
}
System.out.println("获得包括私有属性");
System.out.println(clazz.getDeclaredField("id"));
System.out.println("获得所有包括私有属性");
Field[] fields1 = clazz.getDeclaredFields();
for(int j=0;j<fields1.length;j++){
Field item2 = fields1[j];
System.out.println(item2);
}
}
}
class A{
private Integer id;
public String name;
public String otherName;
}
···
## 4. 设置和获得属性具体值
- void setAccessible(boolean flag) throws SecurityException(true取消);语言访问检查(允许访问私有)
- void set(Object obj,Object value)(obj传入实例化对象,静态属性则为null);
- Object get(Object obj)(obj传入实例化对象,静态属性则为null)
```java
public class Main {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
Class<A> clazz = A.class;
A a = new A();
//public修饰的属性
Field field = clazz.getField("name");
field.set(a,"haha");
System.out.println(field.get(a));
//private修饰的属性
Field id = clazz.getDeclaredField("id");
id.setAccessible(true);//注意访问私有属性要这行代码
id.set(a,100);
System.out.println(id.get(a));
}
}
class A{
private Integer id;
public String name;
}
5.获得方法
- Method getMethod(String name, Class<?>… parameterTypes)(本类及父类public)
- Method getDeclaredMethod(String name, Class<?>… parameterTypes)(本类所有公开方法
- Method[] getMethods() (本类及父类public)
- Method[] getDeclaredMethods() (本类All)
public class Main {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class<A> clazz = A.class;
System.out.println("获得public修饰的方法");
Method method = clazz.getMethod("fun");
System.out.println(method);
System.out.println("获得public修饰的所有方法");
Method[] methods = clazz.getMethods();
for(int i=0;i<methods.length;i++){
Method item = methods[i];
System.out.println(item);
}
System.out.println("获得包括私有方法");
System.out.println(clazz.getDeclaredMethod("fun",String.class));
System.out.println("获得所有方法");
Method[] methods1 = clazz.getDeclaredMethods();
for(int j=0;j<methods1.length;j++){
Method item2 = methods1[j];
System.out.println(item2);
}
}
}
class A{
public void fun(){
System.out.println("public fun");
}
private void fun(String name){
System.out.println("private fun");
}
}
6.调用对象的方法
Object invoke(Object obj,Object… args)(obj传入实例化对象,静态方法则为null)
public class Main {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class<A> clazz = A.class;
A a = new A();
System.out.println("获得public修饰的方法");
Method method = clazz.getMethod("fun");
method.invoke(a,null);
System.out.println("获得包括私有方法");
Method fun = clazz.getDeclaredMethod("fun", String.class);
fun.setAccessible(true);//私有方法需要允许访问
fun.invoke(a,"fun");
}
}
class A{
public void fun(){
System.out.println("public fun");
}
private void fun(String name){
System.out.println("my name is" + name);
}
}
访问私有构造,私有方法和私有属性都要setAccessible(true)才能使用
总结
本文介绍了java反射,如果有任何疑问欢迎私信或者评论