简体   繁体   English

JAVA是否有可能动态地让一个类扩展另一个?

[英]JAVA Is it possible to dynamically have a class extend another?

I've been at this since yesterday looking for a way to do this. 我从昨天起就一直在寻找一种方法来做到这一点。 What I have are hundreds of POJOs from a third party and need to apply properties to these based on business rules. 我所拥有的是来自第三方的数百个POJO,需要根据业务规则将属性应用于这些POJO。 I'm avoiding the altering of the POJOs because the third party could potentially recreate them thus creating a nightmare for managing files down the road. 我正在避免改变POJO,因为第三方可能会重新创建它们,从而造成管理文件的噩梦。

What I'm attempting to do is to dynamically have a class extend another class. 我试图做的是动态地让一个类扩展另一个类。 For example. 例如。

POJO: Foo.java POJO:Foo.java

package abc.service;

public class Foo {
    private String greeting = "";

    public Foo(){
        gretting = "Good morning";
    }

    public String getGreeting(){
        return greeting;
    }
}
// end file

Mine: Bar.java 我的:Bar.java

package abc.service;

public class Bar {
    private String claim = "";

    public Bar(){
        claim = "You're correct";
    }

    public String getClaim(){
        return claim;
    }
}
// end file

Mine: TestMe.java 我的:TestMe.java

Trying here in a class separate from the POJOs to have a POJO extend another of my classes. 在与POJO分开的类中尝试使用POJO扩展我的另一个类。

Is this beyond the abilities of JAVA? 这超出了JAVA的能力吗?

package abc;

public class TestMe {
    Foo f = new Foo();
    Class c1 = f.getClass();

    Bar b = new Bar();
    Class c2 = b.getClass();

    Class merged = c2.asSubclass(c1);

    // Trying to call the Foo method
    System.out.println(merged.getGreeting());
    // Trying to call the Bar method
    System.out.println(merged.getClaim());
}

Additionally what is going on is that JSON schemas are being created from the POJOs that are provided. 另外,正在发生的是从提供的POJO创建JSON模式。 But the POJOs are only based on an UPDATE record scenario. 但POJO仅基于UPDATE记录方案。 I'm looking for the best way to have the POJOs extend another class for CREATE record scenarios which is why I'm looking to dynamically have their POJOs extend my code when required. 我正在寻找让POJO为CREATE记录场景扩展另一个类的最佳方法,这就是为什么我希望动态地让他们的POJO在需要时扩展我的代码。

  • Need to generate json schema for the POJOs for UPDATE 需要为POJO生成更新的json模式
  • Need to verifying their json meets the POJOs requirements for UPDATE 需要验证他们的json符合POJO UPDATE的要求
  • Need to convert their json to the POJOs for UPDATE 需要将他们的json转换为POJO以进行更新

Also, 也,

  • Need to generate json schema for the POJOs for CREATE 需要为POJO创建用于CREATE的json模式
  • Need to verifying their json meets the POJOs requirements for CREATE 需要验证他们的json是否满足CREJ的POJO要求
  • Need to convert their json to the POJOs for CREATE 需要将他们的json转换为POJO for CREATE

Using Jackson Mixin and the ObjectMapper I'm able to dynamically apply my code to the classes when creating the schemas but the issue I'm having is when trying to have the POJOs extend the class where Mixin is not going to solve the issue. 使用Jackson Mixin和ObjectMapper我能够在创建模式时动态地将我的代码应用于类,但我遇到的问题是当试图让POJO扩展Mixin不能解决问题的类时。

With plain Java: no, it can't be done. 使用普通Java:不,它无法完成。

You can change byte code, either in the build process, or at runtime. 您可以在构建过程中或在运行时更改字节代码。 But it's hard, and there's not a lot of documentation. 但这很难,并且没有很多文档。

AspectJ's declare parents expression is probably the easiest way to do it at build time. AspectJ的declare parents表达式可能是在构建时执行它的最简单方法。

If you want to do it at runtime, look at frameworks like asm, CGLib or ByteBuddy. 如果您想在运行时执行此操作,请查看asm,CGLib或ByteBuddy等框架。 But you will have to run the code from inside a custom ClassLoader or agent. 但是您必须从自定义ClassLoader或代理程序中运行代码。

You can use composition instead of inheritance. 您可以使用合成而不是继承。

public class Foo {
    private String greeting = "";

    public Foo(){
        gretting = "Good morning";
    }

    public String getGreeting(){
        return greeting;
    }
}

Your class 你的班

public class Bar {
    private String claim = "";
    private Foo foo;

    public Bar(){
        claim = "You're correct";
        foo = new Foo();
    }

    public String getClaim(){
        return claim;
    }

    public Foo getFoo(){
        return foo;
    }
}

And the test 而且测试

public class TestMe {

    // Trying to call the Foo method
    System.out.println(bar.getFoo().getGreeting());
    // Trying to call the Bar method
    System.out.println(bar.getClaim());
}

Or you can do you class a little bit different. 或者你可以让你上课有点不同。

public class Bar {
        private String claim = "";
        private Foo foo;

        public Bar(){
            claim = "You're correct";
            foo = new Foo();
        }

        public String getClaim(){
            return claim;
        }

        public String getGreeting(){
            return foo.getGreeting();
        }
    }

And the test 而且测试

public class TestMe {

    // Trying to call the Foo method
    System.out.println(bar.getGreeting());
    // Trying to call the Bar method
    System.out.println(bar.getClaim());
}

It is Not Possible. 这不可能。

Simply to put, JAVA at present(till latest version) does not have a provision to dynamically extend the class at runtime and load to JVM. 简而言之,JAVA目前(直到最新版本)没有在运行时动态扩展类并加载到JVM的规定。

Instead of extending, you should use a design pattern. 您应该使用设计模式,而不是扩展。 For example the Stategy Pattern . 例如, Stategy Pattern This allows you to change your strategy dynamicaly. 这允许您动态地更改策略。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM