java反射之详解

简介: 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));
  }
}
}

运行结果

小贴士 :可以根据场景使用

制作不易,希望多多鼓励。

目录
相关文章
|
1月前
|
监控 Java
Java基础——反射
本文介绍了Java反射机制的基本概念和使用方法,包括`Class`类的使用、动态加载类、获取方法和成员变量信息、方法反射操作、以及通过反射了解集合泛型的本质。同时,文章还探讨了动态代理的概念及其应用,通过实例展示了如何利用动态代理实现面向切面编程(AOP),例如为方法执行添加性能监控。
|
1月前
|
Java
Java的反射
Java的反射。
29 2
|
2月前
|
存储 Java
[Java]反射
本文详细介绍了Java反射机制的基本概念、使用方法及其注意事项。首先解释了反射的定义和类加载过程,接着通过具体示例展示了如何使用反射获取和操作类的构造方法、方法和变量。文章还讨论了反射在类加载、内部类、父类成员访问等方面的特殊行为,并提供了通过反射跳过泛型检查的示例。最后,简要介绍了字面量和符号引用的概念。全文旨在帮助读者深入理解反射机制及其应用场景。
38 0
[Java]反射
|
3月前
|
安全 Java 索引
Java——反射&枚举
本文介绍了Java反射机制及其应用,包括获取Class对象、构造方法、成员变量和成员方法。反射允许在运行时动态操作类和对象,例如创建对象、调用方法和访问字段。文章详细解释了不同方法的使用方式及其注意事项,并展示了如何通过反射获取类的各种信息。此外,还介绍了枚举类型的特点和使用方法,包括枚举的构造方法及其在反射中的特殊处理。
77 9
Java——反射&枚举
|
2月前
|
安全 Java 测试技术
🌟Java零基础-反射:从入门到精通
【10月更文挑战第4天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
31 2
|
3月前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
|
2月前
|
IDE Java 编译器
java的反射与注解
java的反射与注解
23 0
|
3月前
|
Java 程序员 编译器
Java的反射技术reflect
Java的反射技术允许程序在运行时动态加载和操作类,基于字节码文件构建中间语言代码,进而生成机器码在JVM上执行,实现了“一次编译,到处运行”。此技术虽需更多运行时间,但广泛应用于Spring框架的持续集成、动态配置及三大特性(IOC、DI、AOP)中,支持企业级应用的迭代升级和灵活配置管理,适用于集群部署与数据同步场景。
|
3月前
|
存储 安全 Java
扫盲java基础-反射(一)
扫盲java基础-反射(一)
|
3月前
|
Java
扫盲java基础-反射(二)
扫盲java基础-反射(二)