如何访问第三方库中受保护的 Java 方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6413309/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 15:47:37  来源:igfitidea点击:

How do you access protected Java method in thirdparty library?

javamethodsprotected

提问by salman.mirghasemi

Assume that you must access a protected method of a Java object that you receive somewhere in your code. What is your solution?

假设您必须访问在代码中某处收到的 Java 对象的受保护方法。你的解决方案是什么?

I know one approach: You can employ reflection and call setAccessible(true) on the Method object.

我知道一种方法:您可以使用反射并在 Method 对象上调用 setAccessible(true) 。

Any other idea?

还有其他想法吗?

采纳答案by rsp

As per the Java access modifiers, besides extending the object (which you can't if you receive the object) is to access it from an object in the same package as the object you received. So your option is to create a wrapper class in the same packagewhich retrieves the attribute via the protected method for you.

根据Java 访问修饰符,除了扩展对象(如果您收到对象就不能扩展)是从与您收到的对象相同的包中的对象访问它。所以你的选择是在同一个包中创建一个包装类,它通过受保护的方法为你检索属性。

回答by pap

You can subclass the method, create a public method that calls the protected method and returns the result.

您可以对方法进行子类化,创建一个调用受保护方法并返回结果的公共方法。

If you can't do that (if the class is final), then setAccessible is pretty much your only way.

如果你不能这样做(如果课程是最终的),那么 setAccessible 几乎是你唯一的方法。

回答by Bala R

One other option is to create a class that extends that 3rd party class that has the protected method that you are interested in.

另一种选择是创建一个类来扩展具有您感兴趣的受保护方法的第 3 方类。

public class ThirdPartyClass
{
   protected void foo(){}
}

and

public MyClass extends ThirdPartyClass
{

     public void callFoo()
     {
           foo();
     }

}

回答by Reverend Gonzo

You can also extend the class, override the method, and make the overridden method be public. Then have it just call super.method().

您还可以扩展类,覆盖方法,并使覆盖的方法成为公共方法。然后让它调用super.method()。

回答by planetjones

The other way is to extend the Class (if possible) and get access to the protected method via inheritance. If you do not create the Object this is not possible, as you would need it at compile time and you would need to create the Object yourself.

另一种方法是扩展类(如果可能)并通过继承访问受保护的方法。如果您不创建对象,这是不可能的,因为您在编译时需要它并且您需要自己创建对象。

A dodgy solution could be to use composition. So you create a class in the same package e.g. OtherObjectWrapper. As it's in the same package you could call the Object's protected method through a public API you expose. This is not recommended though, as you don't own the package which you are adding a Class too and you can make your code very brittle e.g.

一个狡猾的解决方案可能是使用组合。所以你在同一个包中创建一个类,例如OtherObjectWrapper。由于它在同一个包中,您可以通过公开的公共 API 调用对象的受保护方法。但是,不建议这样做,因为您也不拥有要添加 Class 的包,并且您可能会使代码变得非常脆弱,例如

package com.foo;

public class OtherObjectWrapper {
   private com.foo.OtherObject wrappedObject;

   public OtherObjectWrapper(com.foo.OtherObject wrappedObject) {
     this.wrappedObject = wrappedObject;
   }

   public void callTheProtectedMethod() {
     wrappedObject.callTheProtectedMethod();
   }
}

Consider what the the API designer thinking when they marked the method as protected? Maybe they didn't have a clue what they were doing and it should be public, or worse still, it should be package private or private outright. Or maybe they did and they determined only code in the same package or through inheritance should have access to the protected method. If it's protected it may well be for a reason, so be wary as you may tie your codes behaviour to behaviours which may change and break your code. Also look at who owns the third party Object and whether there is a better API for accessing the protected method's functionality.

考虑一下 API 设计者在将方法标记为受保护时的想法?也许他们不知道他们在做什么,它应该是公开的,或者更糟糕的是,它应该完全私有或私有。或者也许他们确实这样做了,并且他们确定只有同一包中的代码或通过继承才能访问受保护的方法。如果它受到保护,那很可能是有原因的,所以要小心,因为您可能会将您的代码行为与可能改变和破坏您的代码的行为联系起来。还要查看谁拥有第三方对象以及是否有更好的 API 来访问受保护方法的功能。

回答by Sergio

If you can put the calling class in the same package you will have access to the method. This and inheriting from that class are the only non-reflective ways to access a protected method.

如果您可以将调用类放在同一个包中,您将可以访问该方法。这个和从那个类继承是访问受保护方法的唯一非反射方式。

回答by Thomas

As already said, subclassing is normally the standard way to access that method. Other approaches (wrapper in same package, reflection) should generally not used, since if you can't extend the class (due to being final) there often are good reasons accessing that method is made hard.

如前所述,子类化通常是访问该方法的标准方式。通常不应使用其他方法(同一包中的包装器、反射),因为如果您不能扩展类(由于是最终的),通常有充分的理由访问该方法会变得困难。

If the library is of any decent quality you definitely shouldn't have to use any other means besides subclassing to access a protected method or not access that method at all.

如果库的质量不错,除了子类化之外,您绝对不必使用任何其他方式来访问受保护的方法或根本不访问该方法。