讲师中心 微信公众号
AI工具推荐 视频效率加速

Java中在抽象基类main方法内动态实例化派生类的完整教程

老墨小哥_4883

老墨小哥_4883

发布时间:2026-02-04 19:29:02

|

838人浏览过

|

来源于php中文网

原创

Java中在抽象基类main方法内动态实例化派生类的完整教程

本文讲解如何在抽象基类的静态main方法中,根据运行时调用的子类名(如java mone 5)自动识别并实例化对应的具体子类,从而调用其multiply()方法完成计算,避免硬编码、实现灵活可扩展的命令行工具模式。

在Java中,抽象基类无法直接实例化,但其main方法作为程序入口点仍可被继承类间接调用——关键在于:main方法属于类,而非对象;它不依赖于当前类是否被实例化,而取决于JVM启动时指定的主类。因此,当执行 java MOne 5 时,JVM实际加载并运行的是 MOne 类的 main 方法(若未重写,则继承自 Calculation),此时 this 的运行时类型就是 MOne。

但原问题中 Calculation.main() 是 static 且 final 的,无法被重写,且希望所有子类共用同一份逻辑(解析参数、调用 multiply),同时又能“知道自己是谁”。最简洁、健壮且符合JVM机制的解法是:利用反射获取当前正在执行 main 方法的类(即启动类),然后实例化它——无需扫描整个类路径,也无需第三方库。

以下是推荐实现(零依赖、高效、安全):

public abstract class Calculation {
    public abstract int multiply(int x);

    public static void main(String[] args) {
        // 1. 获取当前正在执行 main 的具体类(如 MOne、MTwo)
        Class<?> callerClass = null;
        for (StackTraceElement e : Thread.currentThread().getStackTrace()) {
            if ("main".equals(e.getMethodName()) && e.getClassName() != Calculation.class.getName()) {
                try {
                    callerClass = Class.forName(e.getClassName());
                    break;
                } catch (ClassNotFoundException ignored) {}
            }
        }

        if (callerClass == null || !Calculation.class.isAssignableFrom(callerClass)) {
            System.err.println("Error: No valid Calculation subclass found in call stack.");
            return;
        }

        // 2. 实例化该子类(要求有无参构造器)
        Calculation instance;
        try {
            instance = (Calculation) callerClass.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            System.err.println("Failed to instantiate " + callerClass.getSimpleName() + ": " + e.getMessage());
            return;
        }

        // 3. 解析参数并调用 multiply
        if (args.length == 0) {
            System.out.println("Usage: java <Subclass> <number>");
            return;
        }
        try {
            int x = Integer.parseInt(args[0]);
            System.out.println(instance.multiply(x));
        } catch (NumberFormatException e) {
            System.err.println("Invalid number argument: " + args[0]);
        }
    }
}

配套子类保持原样(确保有默认构造器):

Java调试
Java调试

通过 JDWP 实现 Java 远程调试:连接远程 JVM、设置断点、单步执行代码、查看变量值、获取调用栈。适用于需要调试远程 Java 应用、排查运行时状态、追踪代码执行流程的场景。 术语注解 JDWP:Java Debug Wire Protocol,Java 调试有线协议(Java 远程调试底层通信协议) remote JVM:远程 Java 虚拟机 step through code:代码单步调试(步入 / 步过 / 步出调试) inspect variables:变量查看 / 变量检视 stac

下载

立即学习“Java免费学习笔记(深入)”;

public class MOne extends Calculation {
    @Override
    public int multiply(int x) { return x; }
}

public class MTwo extends Calculation {
    @Override
    public int multiply(int x) { return 2 * x; }
}

public class MThree extends Calculation {
    @Override
    public int multiply(int x) { return 3 * x; }
}

✅ 运行效果:

$ java MOne 5    # 输出: 5
$ java MTwo 5    # 输出: 10
$ java MThree 5  # 输出: 15

⚠️ 注意事项:

  • 所有子类必须提供无参构造器(默认即满足);
  • 此方案依赖 Thread.getStackTrace(),虽属标准API,但在某些高度优化或安全受限环境(如部分Java模块系统配置)中可能受限,生产环境建议配合 --add-opens java.base/java.lang=ALL-UNNAMED 启动参数;
  • 若需支持多参数(如 java MTwo 5 3),可扩展 multiply 方法签名并调整解析逻辑;
  • 不推荐使用类路径扫描(如ClassGraph)方案:它性能开销大、依赖外部库、无法精准区分“本次启动的子类”,易导致误触发多个子类实例。

总结:核心思想是“让main知道谁启动了它”,而非“让基类去猜有哪些子类”。这既符合面向对象设计原则,又具备最佳运行时效率与可维护性。

热门AI工具

更多
SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

咔片AIPPT

一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

花生AI
花生AI Hot

一款AI视频创作工具,主要用于B站推出的AI视频创作工具,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

码上飞
码上飞 Hot

一款基于自然语言的AI应用开发平台,可根据用户描述自动生成应用程序,帮助个人和团队快速完成应用原型与开发。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

相关专题

更多
go语言 面向对象
go语言 面向对象

本专题整合了go语言面向对象相关内容,阅读专题下面的文章了解更多详细内容。

7395

2025.09.05

java面向对象
java面向对象

本专题整合了java面向对象相关内容,阅读专题下面的文章了解更多详细内容。

362

2025.11.27

C++ 面向对象编程与设计模式实践
C++ 面向对象编程与设计模式实践

本专题整合了 C++ 面向对象编程的核心机制,涵盖类的定义与访问控制、构造函数与析构函数、拷贝语义与移动语义、继承与虚函数多态、抽象类与接口、运算符重载、友元函数等关键知识点,同时结合单例模式、工厂模式、观察者模式、策略模式等常用设计模式的 C++ 实现,帮助开发者写出结构清晰、易于维护的面向对象代码。

384

2026.04.09

Java 面向对象与核心编程机制
Java 面向对象与核心编程机制

系统讲解 Java 面向对象编程的核心知识体系,涵盖类的定义与封装、构造方法与 this/super 关键字、继承与方法重写、多态与向上向下转型、抽象类与接口的区别与设计原则、异常处理机制(try-catch-finally / 自定义异常)、泛型的类型参数与通配符、集合框架(List/Set/Map)的使用与遍历方式,帮助开发者全面掌握 Java 程序设计的核心机制与面向对象思维。

263

2026.04.17

go语言 面向对象
go语言 面向对象

本专题整合了go语言面向对象相关内容,阅读专题下面的文章了解更多详细内容。

7395

2025.09.05

java面向对象
java面向对象

本专题整合了java面向对象相关内容,阅读专题下面的文章了解更多详细内容。

362

2025.11.27

C++ 面向对象编程与设计模式实践
C++ 面向对象编程与设计模式实践

本专题整合了 C++ 面向对象编程的核心机制,涵盖类的定义与访问控制、构造函数与析构函数、拷贝语义与移动语义、继承与虚函数多态、抽象类与接口、运算符重载、友元函数等关键知识点,同时结合单例模式、工厂模式、观察者模式、策略模式等常用设计模式的 C++ 实现,帮助开发者写出结构清晰、易于维护的面向对象代码。

384

2026.04.09

Java 面向对象与核心编程机制
Java 面向对象与核心编程机制

系统讲解 Java 面向对象编程的核心知识体系,涵盖类的定义与封装、构造方法与 this/super 关键字、继承与方法重写、多态与向上向下转型、抽象类与接口的区别与设计原则、异常处理机制(try-catch-finally / 自定义异常)、泛型的类型参数与通配符、集合框架(List/Set/Map)的使用与遍历方式,帮助开发者全面掌握 Java 程序设计的核心机制与面向对象思维。

263

2026.04.17

DBeaver怎么导入数据
DBeaver怎么导入数据

DBeaver数据导入专题,整理Excel、CSV、SQL、TXT等常见文件的数据导入方法,涵盖目标数据库选择、数据表创建、字段映射、数据类型设置及导入参数配置等操作,帮助用户将本地文件中的数据写入数据库,并了解批量导入、重复数据处理和导入失败等常见问题的解决方法。

20

2026.11.05

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
dev.java 官方:Learn Java
dev.java 官方:Learn Java

共0课时 | 0人学习

Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn