反射

本文介绍了Java反射机制,它可动态实例化对象、读写属性、调用方法。反射相关代码从获得java.lang.Class类对象开始,有Class.forName、类名.class、对象.getClass三种方式。还阐述了反射的三大作用,包括实例化对象、动态调用方法和读写属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. 什么是反射

反射java语言中的一种机制,通过这种机制可以动态的实例化对象、读写属性、调用方法。

二. 一切反射相关的代码都从获得java.lang.Class类对象开始

1 、Class.forName(完整类名)
2、 类名.class
3 、对象.getClass()

注1:ClassNotFoundException(类名错|少jar包)
注2:同一类的、类对象只会创建一个

代码如下:

创建一个student实体类

package com.cjq.reflect;
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());
 }
}

1 、Class.forName(完整类名)

package com.cjq.reflect;
/**
 * 获取类对象的方式 通过Java提供的反射机制获取到com.zking.reflect.Student.class
 * 1、Class.forName("全路径名"); jdbc/自定义mvc框架要用
 * 2、类名.class 结合泛型做通用分页查询方法会用
 * 3、类java.lang.Class实例(Student.class)的类实例的getClass()获取 通用的增删改结合泛型使用
 * 
 * @author cjq
 *
 */
public class Demo1 {
 public static void main(String[] args) throws Exception {
  // 1、Class.forName("全路径名"); jdbc/自定义mvc框架要用
  Class stuClz = Class.forName("com.cjq.reflect.Student");  
 }
}

运行结果如下:
在这里插入图片描述
2、 类名.class

package com.cjq.reflect;
/**
 * 获取类对象的方式 通过Java提供的反射机制获取到com.zking.reflect.Student.class
 * 1、Class.forName("全路径名"); jdbc/自定义mvc框架要用
 * 2、类名.class 结合泛型做通用分页查询方法会用
 * 3、类java.lang.Class实例(Student.class)的类实例的getClass()获取 通用的增删改结合泛型使用
 * 
 * @author cjq
 *
 */
public class Demo1 {
 public static void main(String[] args) throws Exception {
    // 2、类名.class 结合泛型做通用分页查询方法会用
    Class stuClz = Student.class;
    System.out.println(stuClz);
 }
}

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

3 、对象.getClass()

package com.cjq.reflect;
/**
 * 获取类对象的方式 通过Java提供的反射机制获取到com.zking.reflect.Student.class
 * 1、Class.forName("全路径名"); jdbc/自定义mvc框架要用
 * 2、类名.class 结合泛型做通用分页查询方法会用
 * 3、类java.lang.Class实例(Student.class)的类实例的getClass()获取 通用的增删改结合泛型使用
 * 
 * @author cjq
 *
 */
public class Demo1 {
 public static void main(String[] args) throws Exception {
      Student stu = new Student();
      // 3、类java.lang.Class实例(Student.class)的类实例的getClass()获取 通用的增删改结合泛型使用
      Class stuClz = stu.getClass();
      System.out.println(stuClz); 
      }
}

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

三、反射三大作用(java.lang.reflect.*)

1 、实例化对象
c.newInstance()
Constructor.getConstructor/Constructor.getDeclaredConstructor

:一定要提供无参构造器

代码如下:

package com.cjq.reflect;
import java.lang.reflect.Constructor;/**
 * 利用反射进行对象的实例化 之前:通过new关键字进行实例化 现在: 通过java.lang.reflect.construct来实例化对象 优势:
 * 1、能够对未知的对象进行实例化 
 * 2、能够对私有构造器实例化对象
 * 
 * @author cjq
 *
 */
public class Demo2 {
 public static void main(String[] args) throws Exception, IllegalAccessException {
  // Student stu = new Student();
  // Class stuClz = stu.getClass();
  Class<Student> stuClz = Student.class;  
  
  /*// 1.newInstance这个方法默认是使用无参构造器去实例化对象
  Student stu2 = (Student) stuClz.newInstance();
  System.out.println(stu2);*/ 
  
 /*// 2.调用有参构造器去实例化对象
   Constructor<Student> constructor = stuClz.getConstructor(String.class);
   Student stu2 = (Student) constructor.newInstance("zs");*/  
   
   /*// 3.调用有构造器去实例化对象
   Constructor<Student> constructor =stuClz.getConstructor(String.class,String.class);
   Student stu2 = (Student) constructor.newInstance("s001","zs");*/  
   
   // 4.调用私有构造器去实例化对象
  // java.lang.NoSuchMethodException:
  // getConstructor与getDeclaredConstructor的区别(getConstructor只能获取被public修饰的构造器,getDeclaredConstructor被所有关键字修饰的构造器)
  // Class com.cjq.reflect.Demo2 can not access a member of class
  // com.cjq.reflect.Student with modifiers "private"   
  
   Constructor<Student> constructor =stuClz.getDeclaredConstructor(Integer.class);
    constructor.setAccessible(true); 
    Student stu2 = (Student)constructor.newInstance(18);
   
 }
}

运行结果如下:
在这里插入图片描述
2 、动态调用方法
Method m;
m.invoke

代码如下:

package com.cjq.reflect;
import java.lang.reflect.Method;/**
 * 动态方法调用
 *  构造方法是不是方法?
 * 
 * @author cjq
 *
 */
public class Demo3 {
 public static void main(String[] args) throws Exception, SecurityException {
  Student stu = new Student();
  Class<? extends Student> stuClz = stu.getClass();
//  Method m= stuClz.getDeclaredMethod("hello");
//  m.invoke(stu);
  
//  Method m= stuClz.getDeclaredMethod("hello",String.class);
//  m.invoke(stu,"zs");
  
  Method m= stuClz.getDeclaredMethod("add",Integer.class,Integer.class);
  m.setAccessible(true);
//  Method.invoke的返回值是被动态调用的方法的返回值
  Object invoke = m.invoke(stu,20,5);
  System.out.println(invoke);
 }
}

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

3 、读写属性
Field set/get
代码如下:

package com.cjq.reflect;
import java.lang.reflect.Field;/**
 * 反射读写属性 自定义标签库、通用分页、自定义mvc也要用
 * 
 * 5. 访问修饰符
   getModifiers()
    java:
    private 1
    protected 2
    public 4
    static 8
    final abstract....
    怎么判定属性或方法被那些修饰符所修饰呢?
    getModifiers
    3 private protected
    5 
    
 * 
 * @author cjq
 *
 */
public class Demo4 {
 public static void main(String[] args) throws Exception {
  Student stu = new Student("s001", "zs");
  stu.age = 22;
  System.out.println(stu.getSid());
  System.out.println(stu.getSname());
  Class<? extends Student> stuClz = stu.getClass();  
  
  // Field f = stuClz.getDeclaredField("age");
  // f.setAccessible(true);
  // System.out.println(f.get(stu));  
  
  // 获取当前Student实例中的stu所有属性及其属性值
  Field[] fields = stuClz.getDeclaredFields();
  for (Field field : fields) {
   field.setAccessible(true);
   System.out.println(field.getName() + ":" + field.get(stu));
  }
 }}

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

内容概要:该研究通过在黑龙江省某示范村进行24小时实地测试,比较了燃煤炉具与自动/手动进料生物质炉具的污染物排放特征。结果显示,生物质炉具相比燃煤炉具显著降低了PM2.5、CO和SO2的排放(自动进料分别降低41.2%、54.3%、40.0%;手动进料降低35.3%、22.1%、20.0%),但NOx排放未降低甚至有所增加。研究还发现,经济性和便利性是影响生物质炉具推广的重要因素。该研究不仅提供了实际排放数据支持,还通过Python代码详细复现了排放特征比较、减排效果计算和结果可视化,进一步探讨了燃料性质、动态排放特征、碳平衡计算以及政策建议。 适合人群:从事环境科学研究的学者、政府环保部门工作人员、能源政策制定者、关注农村能源转型的社会人士。 使用场景及目标:①评估生物质炉具在农村地区的推广潜力;②为政策制定者提供科学依据,优化补贴政策;③帮助研究人员深入了解生物质炉具的排放特征和技术改进方向;④为企业研发更高效的生物质炉具提供参考。 其他说明:该研究通过大量数据分析和模拟,揭示了生物质炉具在实际应用中的优点和挑战,特别是NOx排放增加的问题。研究还提出了多项具体的技术改进方向和政策建议,如优化进料方式、提高热效率、建设本地颗粒厂等,为生物质炉具的广泛推广提供了可行路径。此外,研究还开发了一个智能政策建议生成系统,可以根据不同地区的特征定制化生成政策建议,为农村能源转型提供了有力支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值