目录
一、反射的核心概念
二、反射基础API
2.1 获取Class对象的四种方式
2.2 访问私有字段
2.3 动态创建对象
2.4 获取所有字段信息
2.5 调用方法(Method)
三、反射的实战场景
3.1 案例 1:XML 配置 + 反射实现 “可配置” 工厂
3.2 案例 2:依赖注入(DI)的简单实现
一、反射的核心概念
Java反射(Reflection)是Java语言的一个重要特性,是 Java 的一种**运行时机制**,通过`java.lang.reflect`包中的 API,程序可以在运行时动态地获取类的信息、创建对象、调用方法和访问字段。反射机制打破了Java的封装性,同时提供了极大的灵活性。
核心特点:
-
运行时类型检查:在运行时获取类的完整结构信息
-
动态操作:动态创建对象、调用方法、访问字段
-
突破封装:可以访问私有成员(通过setAccessible(true))
二、反射基础API
2.1 获取Class对象的四种方式
-
类名.class 和 ClassLoader加载 不会触发类的初始化(静态代码块、构造函数不执行)。
-
对象.getClass 会触发类的初始化(如
Stu的静态代码块、构造函数会执行)。 -
Class.forName("类的全路径”) 会执行静态代码块
package com.demo1;
public class Stu {
private int age = 100;
static {
System.out.println("Stu的静态块执行");
}
public Stu() {
System.out.println("Stu的无参构造函数被调用");
}
}
package com.demo1;
//import com.sun.org.apache.bcel.internal.util.ClassLoader;
public class Test {
public static void main(String[] args) {
// 获取Stu类的变量,构造函数、方法
// 反射的四个入口方式,加载这个类的Class类型
// 1. 类名.class (不会触发初始化)
// Class c1 = Stu.class;
// System.out.println(c1);
// 2. 对象.getClass (执行静态块和无参构造函数)
// Class c2 = new Stu().getClass();
// 3.Class.forName("类的全路径”) (执行静态块)
// try {
// Class c3 = Class.forName("com.demo1.Stu");
// } catch (ClassNotFoundException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// 4. 通过类的加载器ClassLoader (不会触发初始化)
// Class c4 = null;
// try {
// c4 = ClassLoader.getSystemClassLoader().loadClass("com.demo1.Stu");
// } catch (ClassNotFoundException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
}
}
2.2 访问私有字段
- 反射可以访问类的所有字段(包括私有字段)
- 方法newInstance()调用默认无参构造函数
package com.demo1;
public class User {
private int a = 10; // 私有字段
public User() {
System.out.println("调用User的无参构造函数");
}
}
package com.demo1;
import java.lang.reflect.Field;
public class Test {
public static void main(String[] args) {
//传统的面向对象的思想
// User u = new User();
// System.out.println(u.a);
//反射API
//获取User这个类的Class对象
Class targetClass = User.class;
try {
// 创建这个类的对象,基于反射机制,newInstance()调用默认无参构造函数
Object obj = targetClass.newInstance();
// 获取这个类的属性变量a的Field类型。获取名为"a"的字段(包括私有字段)
Field f = targetClass.getDeclaredField("a");
// 设置暴力访问
f.setAccessible(true);
// 通过Field对象的get()方法获取指定对象的字段值。
Object aValue = f.get(obj);
System.out.println(aValue);
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行结果:

2.3 动态创建对象
通过`Class`对象,可以动态创建类的实例:
package com.demo4;
public class User {
public int id;
public String name;
public User() {
this.name = "六神";
}
public User(int id, String name) {
this.id = id;
this.name = name;
}
}
package com.demo4;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class Test {
public static void main(String[] args) throws Exception {
Class userClass = User.class;
// 方式1:调用无参构造函数(需类有无参构造)
Object user1 = userClass.newInstance();
Field f1 = userClass.getDeclaredField("name");
Object obj1 = f1.get(user1);
System.out.println("user1的姓名为: " + obj1);
// 方式2:通过Constructor调用指定构造函数
// 获取带参数的构造函数
Constructor constructor = userClass.getConstructor(int.class, String.class);
// 创建实例并传入参数
Object user2 = constructor.newInstance(9, "花露水");
Field f2 = userClass.getDeclaredField("name");
Object obj2 = f2.get(user2);
System.out.println("user2的姓名为: " + obj2);
}
}
运行结果:

2.4 获取所有字段信息
package com.demo2;
public class User {
private int a = 10;
public String name = "QQ";
protected int count = 100;
}
package com.demo2;
import java.lang.reflect.Field;
public class Test {
public static void main(String[] args) {
try {
Class c = Class.forName("com.demo2.User");
Object newObj = c.newInstance();
// 获取这个类中所有定义的变量(加了s)
Field[] fs = c.getDeclaredFields();
// 只能获取类的public字段
// Field[] fs= c.getFields();
for (Field f : fs) {
f.setAccessible(true);
System.out.println("变量名为: " + f.getName() + " 值为:" + f.get(newObj));
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行结果:

2.5 调用方法(Method)
反射可以调用类的所有方法(包括私有方法):
public static void main(String[] args) throws Exception {
System.out.println("请问你要执行哪个类?");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String name = br.readLine();
Config config = maps.get(name); // 获取配置
if (null == config) {
throw new ActionException("没有匹配的执行类");
}
Class c = Class.forName(config.getPath()); // 加载类
Method m = c.getDeclaredMethod(config.getMname(), null); // 获取方法
m.invoke(c.newInstance(), null); // 反射的执行方法
}
三、反射的实战场景
3.1 案例 1:XML 配置 + 反射实现 “可配置” 工厂
通过 XML 配置类的全限定名,动态创建对象,实现 “新增类无需修改代码,只需修改配置文件里的内容”。
工程目录结构

XML 配置文件(application.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean name="dog" path="com.demo8.Dog" ></bean>
<bean name="cat" path="com.demo8.Cat"></bean>
<bean name="person" path="com.demo8.Person"></bean>
</beans>
接口与实现类
// 接口
package com.demo8;
public interface Animal {
public void eat();
}
// 实现类
package com.demo8;
public class Cat implements Animal{
public void eat() {
// TODO Auto-generated method stub
System.out.println("猫吃鱼");
}
}
package com.demo8;
public class Dog implements Animal{
public void eat() {
// TODO Auto-generated method stub
System.out.println("狗吃骨头");
}
}
package com.demo8;
public class Person implements Animal{
public void eat() {
// TODO Auto-generated method stub
System.out.println("人吃米饭");
}
}
解析 XML + 反射创建对象
package com.demo8;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Hashtable;
import java.util.List;
import java.util.Properties;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class ParseXML {
private static ParseXML px; // 单例实例
private static Hashtable<String, String> tabs = new Hashtable<String, String>(); // 配置缓存
// 私有构造函数 - 读取配置
private ParseXML() {
Properties p = new Properties();
try {
p.load(new FileInputStream("./config.properties"));
String xmlPath = p.getProperty("xmlPath"); // 获取XML路径(application.xml)
System.out.println("XML路径: " + xmlPath);
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read(new File(xmlPath));
// 方案1:绝对路径
// List<Element> lists =(List<Element>) doc.selectNodes("/beans/bean");
// 方案2:相对路径(从根节点开始)
List<Element> lists = doc.getRootElement().elements("bean");
for (Element currentElement : lists) {
// System.out.println(currentElement.getName());
String name = currentElement.attributeValue("name");
String path = currentElement.attributeValue("path");
tabs.put(name, path); // 存入缓存
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 单例获取方法
public synchronized static ParseXML getInstance() {
if (null == px) {
px = new ParseXML();
}
return px;
}
public static Hashtable<String, String> getTabs() {
return tabs;
}
public static void setTabs(Hashtable<String, String> tabs) {
ParseXML.tabs = tabs;
}
}
package com.demo8;
import java.util.Hashtable;
public class AnimalFactory {
private static Animal an;
public static Animal getAnimal(String name) {
// 配置文件+反射机制 an = 容器类.getBean(name)
Hashtable<String, String> tabs = ParseXML.getInstance().getTabs();
String path = tabs.get(name); // 根据名称获取类路径
if (path == null || "".equals(path)) {
throw new PathException("没有匹配的值");
}
try {
Class c = Class.forName(path);
an = (Animal)c.newInstance(); // 反射创建实例
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return an;
}
}
自定义异常
package com.demo8;
public class PathException extends RuntimeException {
public PathException(String msg)
{
super(msg);
}
}
测试类
package com.demo8;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
System.out.println("请用户输入需要的类型:");
Scanner s = new Scanner(System.in);
String name =s.next();
Animal an = AnimalFactory.getAnimal(name);
an.eat();
}
}
运行结果:



3.2 案例 2:依赖注入(DI)的简单实现
通过反射实现 “构造器注入”,动态为对象注入依赖。
工程目录结构

XML 配置文件(app.xml)
<?xml version="1.0" encoding="UTF-8"?>
<app>
<class name="user" path="com.demo3.User" ref="dao" method="actionUser"></class>
<class name="dao" path="com.demo3.UserDao"></class>
</app>
容器核心类(App)
package com.demo3;
import java.io.File;
import java.util.Hashtable;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class App {
private static App app; // 单例实例
private static Hashtable<String, ClassBean> tabs = new Hashtable<String, ClassBean>(); // 配置缓存
// 静态块:启动时加载配置
static {
SAXReader saxReader = new SAXReader();
try {
Document doc = saxReader.read(new File("./app.xml"));
List<Element> lists = doc.selectNodes("./app/class");
for (Element e : lists) {
ClassBean cbean = new ClassBean();
String name = e.attributeValue("name");
String path = e.attributeValue("path");
String ref = e.attributeValue("ref"); // 依赖引用
String method = e.attributeValue("method");
//System.out.println(path + "," + ref + "," + method);
cbean.setPath(path);
if (null != ref || "" != ref) {
cbean.setRef(ref);
}
if (null != method || "" != method) {
cbean.setMethod(method);
}
tabs.put(name, cbean); // 存入缓存
}
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static App getInstance() {
if (null == app) {
app = new App();
}
return app;
}
// 获取配置Bean
public static Object getApplicationBean(String name)
{
return tabs.get(name);
}
public static void main(String[] args) {
ClassBean cbean = (ClassBean)App.getApplicationBean("user");
System.out.println(cbean.getPath()+","+cbean.getRef()+","+cbean.getMethod());
ClassBean cbean1 = (ClassBean)App.getApplicationBean(cbean.getRef());
System.out.println(cbean1.getPath());
}
}
配置信息封装类(ClassBean)
package com.demo3;
public class ClassBean {
private String path; // 类全限定名
private String ref; // 依赖的Bean名称
private String method;// 默认调用方法
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getRef() {
return ref;
}
public void setRef(String ref) {
this.ref = ref;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
}
接口与实现类
// 数据访问接口
package com.demo3;
public interface IDao {
public String execDao();
public String addDao();
}
// Dao实现类1
package com.demo3;
public class Dao implements IDao{
public String execDao()
{
return "查询获取的数据";
}
public String addDao()
{
return "添加用户";
}
}
// Dao实现类2
package com.demo3;
public class UserDao implements IDao{
public String execDao()
{
return "超快查询获取的数据";
}
public String addDao()
{
return "超快添加用户";
}
}
业务类(User)
依赖`IDao`接口,通过**构造器注入**获取实现类:
package com.demo3;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class User {
IDao dao; // 依赖接口,而不是具体实现,便于动态绑定
public User() {
}
// 构造注入
public User(IDao dao) {
this.dao = dao;
}
// Set注入
// public void setUser(IDao dao) {
// this.dao = dao;
// }
public String actionUser() {
//dao = new Dao();
return dao.execDao();
}
public String addUser() {
//dao = new Dao();
return dao.addDao();
}
public static void main(String[] args) {
// 面向对象的方式去调用
// User u = new User();
// String r1 = u.actionUser();
// System.out.println(r1);
// String r2 = u.addUser();
// System.out.println(r2);
try {
ClassBean cbean = (ClassBean) App.getApplicationBean("user");
Class c = Class.forName(cbean.getPath());
System.out.println(cbean.getPath()); // com.demo3.User
// (参数对象的实例化):Dao类/UserDao类的对象通过反射实例化
ClassBean cbean1 = (ClassBean) App.getApplicationBean(cbean.getRef());
System.out.println(cbean1.getPath()); // com.demo3.Dao
Class cdao = Class.forName(cbean1.getPath());
// Object obj = c.newInstance(); //下面用到两次的obj来自于这里new的同一个实例对象
// Setter注入的实例化
// c.getName()得到的是类的全路径,用substring截取类名再和set拼接,得到Set注入的方法名(总体就是通过反射得到setUser方法完成dao的实例化)
// String cname = c.getName().substring(c.getName().lastIndexOf(".") + 1, c.getName().length());
// System.out.println(cname); // cname为User
// String mname = "set" + cname;
// Method daoMethod = c.getDeclaredMethod(mname, IDao.class);
// Object resultObj = daoMethod.invoke(obj, cdao.newInstance()); //(当前类的对象,Dao类/UserDao类的对象)
// System.out.println("已完成实例化");
// 构造器注入
// 获取带参数的构造函数
Constructor constructor = c.getConstructor(IDao.class);
// 使用构造函数创建实例(直接注入依赖)
Object obj = constructor.newInstance(cdao.newInstance());
System.out.println("已完成实例化");
Method m = c.getDeclaredMethod(cbean.getMethod(), null); // 得到actionUser方法
Object result = m.invoke(obj, null);
System.out.println("返回值为:" + result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
运行结果:




这是小红书上一位Java工程师辞职两次的真实经历
可以看出Java如今的就业大环境确实差强人意,那如何拯救现在的Java行业呢?
当然是与新兴技术结合起来,发挥Java最大的作用,提升自己的优势,现如今发展最好的趋势莫过于今年deepseek带火的大模型技术,
Java与大模型结合的技术优势
-
推理环节的核心地位
大模型训练依赖Python生态的高性能计算资源,而Java在推理阶段(模型部署、性能优化、系统集成)具有独特优势。其“编写一次,处处运行”的特性,使其能无缝集成到微服务、分布式系统等企业级架构中,高效处理高并发请求。例如,某电商平台通过Java构建的大模型API网关,支撑每日千万级请求的稳定运行,响应时间缩短50%。 -
生态成熟与性能稳定
Java拥有Spring Boot、Spring Cloud等成熟框架,可快速实现服务注册、负载均衡、熔断降级等生产级能力。JVM的垃圾回收机制和即时编译技术,使其在长连接、高并发场景下表现优于脚本语言。例如,某金融系统采用Java实现大模型推理服务,系统可用率长期保持99.99%以上。 -
兼容性与工程化能力
Java与现有业务系统的兼容性极强,可降低大模型落地的集成成本。例如,某制造企业通过Java将大模型与ERP系统对接,实现生产流程的智能优化,故障率降低30%。同时,Java在代码规范、测试流程、版本管理等方面的积累,能大幅降低大模型项目的研发成本和维护难度。
因此捕获AI,掌握技术是关键,让AI成为我们最便利的工具.
一定要把现有的技术和大模型结合起来,而不是抛弃你们现有技术!掌握AI能力的Java工程师比纯Java岗要吃香的多。
即使现在裁员、降薪、团队解散的比比皆是……但后续的趋势一定是AI应用落地!大模型方向才是实现职业升级、提升薪资待遇的绝佳机遇!
如何学习AGI大模型?
作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
2025最新版优快云大礼包:《AGI大模型学习资源包》免费分享**
一、2025最新大模型学习路线
一个明确的学习路线可以帮助新人了解从哪里开始,按照什么顺序学习,以及需要掌握哪些知识点。大模型领域涉及的知识点非常广泛,没有明确的学习路线可能会导致新人感到迷茫,不知道应该专注于哪些内容。
我们把学习路线分成L1到L4四个阶段,一步步带你从入门到进阶,从理论到实战。

L1级别:AI大模型时代的华丽登场
L1阶段:我们会去了解大模型的基础知识,以及大模型在各个行业的应用和分析;学习理解大模型的核心原理,关键技术,以及大模型应用场景;通过理论原理结合多个项目实战,从提示工程基础到提示工程进阶,掌握Prompt提示工程。

L2级别:AI大模型RAG应用开发工程
L2阶段是我们的AI大模型RAG应用开发工程,我们会去学习RAG检索增强生成:包括Naive RAG、Advanced-RAG以及RAG性能评估,还有GraphRAG在内的多个RAG热门项目的分析。

L3级别:大模型Agent应用架构进阶实践
L3阶段:大模型Agent应用架构进阶实现,我们会去学习LangChain、 LIamaIndex框架,也会学习到AutoGPT、 MetaGPT等多Agent系统,打造我们自己的Agent智能体;同时还可以学习到包括Coze、Dify在内的可视化工具的使用。

L4级别:大模型微调与私有化部署
L4阶段:大模型的微调和私有化部署,我们会更加深入的探讨Transformer架构,学习大模型的微调技术,利用DeepSpeed、Lamam Factory等工具快速进行模型微调;并通过Ollama、vLLM等推理部署框架,实现模型的快速部署。

整个大模型学习路线L1主要是对大模型的理论基础、生态以及提示词他的一个学习掌握;而L3 L4更多的是通过项目实战来掌握大模型的应用开发,针对以上大模型的学习路线我们也整理了对应的学习视频教程,和配套的学习资料。
二、大模型经典PDF书籍
书籍和学习文档资料是学习大模型过程中必不可少的,我们精选了一系列深入探讨大模型技术的书籍和学习文档,它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础。(书籍含电子版PDF)

三、大模型视频教程
对于很多自学或者没有基础的同学来说,书籍这些纯文字类的学习教材会觉得比较晦涩难以理解,因此,我们提供了丰富的大模型视频教程,以动态、形象的方式展示技术概念,帮助你更快、更轻松地掌握核心知识。

四、大模型项目实战
学以致用 ,当你的理论知识积累到一定程度,就需要通过项目实战,在实际操作中检验和巩固你所学到的知识,同时为你找工作和职业发展打下坚实的基础。

五、大模型面试题
面试不仅是技术的较量,更需要充分的准备。
在你已经掌握了大模型技术之后,就需要开始准备面试,我们将提供精心整理的大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。

因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取

3万+

被折叠的 条评论
为什么被折叠?



