简体   繁体   中英

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. 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.

What I'm attempting to do is to dynamically have a class extend another class. For example.

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

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

Trying here in a class separate from the POJOs to have a POJO extend another of my classes.

Is this beyond the abilities of 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. But the POJOs are only based on an UPDATE record scenario. 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.

  • Need to generate json schema for the POJOs for UPDATE
  • Need to verifying their json meets the POJOs requirements for UPDATE
  • Need to convert their json to the POJOs for UPDATE

Also,

  • Need to generate json schema for the POJOs for CREATE
  • Need to verifying their json meets the POJOs requirements for CREATE
  • Need to convert their json to the POJOs 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.

With plain Java: no, it can't be done.

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.

If you want to do it at runtime, look at frameworks like asm, CGLib or ByteBuddy. But you will have to run the code from inside a custom ClassLoader or agent.

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.

Instead of extending, you should use a design pattern. For example the Stategy Pattern . This allows you to change your strategy dynamicaly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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