0

I have 2 classes. I want to replace one, class A so that ANY instance of it will actually behave like class B.

class A {
    fun test() = "a"
}

class B { 
    fun test() = "b"
}

I was trying to use the ClassLoader to do this but I couldn't get the system to call MyClassLoader.

class MyClassLoader() : ClassLoader() {

    @Throws(ClassNotFoundException::class)
    override fun loadClass(name: String): Class<*>? {
        if (name == "com.myapp.A") {
            return B::class.java
        } else return super.loadClass(name)
    }
}

This has to happen at compile time or runtime because I cannot manually replace every instance of A for B. (This is a minimalist example of the problem). A cannot be removed, this is a requirement.

So how do I attach MyClassLoader so that the system uses it?

I tried: Thread.currentThread().setContextClassLoader(MyClassLoader()) but the MyClassLoader doesn't get called.

J_Strauton
  • 2,270
  • 3
  • 28
  • 70
  • Why do you load `A` in the first place? Why not just replace `A` with `B` in the entire code? – Turing85 Feb 09 '20 at 06:56
  • Unfortunately `A` is there and cannot be removed. – J_Strauton Feb 09 '20 at 06:57
  • 1
    Reads like an [XY problem](https://meta.stackexchange.com/q/66377/351454) to me. The ability to choose an implementation separately from the method definitions, at runtime, is what **interfaces** were invented to solve. – Andreas Feb 09 '20 at 07:55
  • It is not XY problem. I simplified the problem for the question. The problem is I need to change the class loader for mine. – J_Strauton Feb 09 '20 at 07:56
  • maybe [Custom ClassLoader, how to use?](https://stackoverflow.com/q/45656836/85421) - just for Java – user85421 Feb 09 '20 at 08:18
  • @user85421 close, but it didn't work – J_Strauton Feb 09 '20 at 08:23
  • 1
    This is not the XY problem, so upvoted and developers needs more control over languages, if this question gets answered it will help the community in securing the java sources from reverse engineering too – Rushikant Pawar Feb 09 '20 at 10:02

2 Answers2

-3

You can use the Factory design pattern. Depending on what kind of class instance you want you can load/return it at runtime from the Factory class static method.

Sumit Basu
  • 35
  • 1
  • 2
-3

i do not know what it will use for but for low scale ,you can try to have only on object that contain the methods and properties of both classes like example

val classType2 = 1
class AB{
    fun testA() = "a"
    fun testB() = "b"
    val classType1 = 1 

   fun test() {
     if(classType1 ==1){testA()}
     else{testB()}    
   }

}

you can add fun to change the class type or,

if you want to change all instances at the same replace classType1 with classType2 at if contition then change value of classType2.

i hope that