【问题标题】:How to call a private method of a class in different package如何调用不同包中类的私有方法
【发布时间】:2013-05-21 13:52:06
【问题描述】:

有一个 BookView.class 有一个私有方法定义如下

  public class BookView{
    private boolean importBook(String epubBookPath){
    //The function that adds books to database.
    }
  }

我正在尝试从不同的包中调用此函数。我的代码是

    protected void onPostExecute(String file_url) {
        // dismiss the dialog after the file was downloaded
        dismissDialog(progress_bar_type);

        /*Now we add the book information to the sqlite file.*/
        TextView textView=(TextView)findViewById(R.id.textView1);
        String filename = textView.getText().toString();
        String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
        String epubBookPath = baseDir+filename;
        Log.i("epubBookPath:",epubBookPath); //No errors till here!

        try {
            Method m=BookView.class.getDeclaredMethod("importBook");
            m.setAccessible(true);//Abracadabra 
            //I need help from here! How do i pass the epubBookPath to the private importBook method.
        } catch (NoSuchMethodException e) {

            e.printStackTrace();
        }
        Intent in = new Intent(getApplicationContext(),
                CallEPubUIActivity.class);        
        startActivity(in);
    }

编辑:

我在 jar 文件中找到了另一个公共方法,它正在执行上述工作。

  public void jsImportBook(String epubBookPath) {
     if (!BookView.this.importBook(epubBookPath))
     return;
   BookView.this.createBookshelf();
  }

【问题讨论】:

  • 私有方法是私有的是有原因的,所以类外没有人调用它们。除非您尝试使用反射,否则您将无法做到这一点,即使那样我也不确定它是否会起作用。
  • 反思是要走的路,但实际上没有人推荐它:stackoverflow.com/questions/880365/…
  • @cmbaxter 我会把它公开,但它是一个 jar 文件的类。我已经使用java反编译器得到它。我无法编辑它。

标签: java


【解决方案1】:

如果您想这样做,您应该将其设为 public 或将其设为 public 包装器方法。

如果那不可能,您可以自行解决,但这很难看而且很糟糕,您应该有真的充分的理由这样做。

public boolean importBook(String epubBookPath){
    //The function that adds books to database.
}

public boolean importBookPublic(String epubBookPath){
    return importBook(epubBookPath);
}
private boolean importBook(String epubBookPath){
    //The function that adds books to database.
}

另请注意,如果您无法直接在第三方库中访问该方法,则很可能是这种方式。查看private 方法的call hierarchy,看看你是否找到了一个public 方法,它可以调用private 方法,并且也可以满足您的需要。

库的设计方式通常是 public 方法进行一些检查(所有参数已给出、已验证等),然后将调用传递给 private 方法以完成实际工作。你几乎不想绕过这个过程。

【讨论】:

  • 你不认为你需要在公共方法中为 importBook(epubBookPath) 指定返回值。
  • @AngeloNeuschitzer 我会把它公开,但它是一个 jar 文件的类。我必须使用java反编译器来解决它。我无法编辑它。有没有办法可以编辑它?感谢您的快速回复。
  • @Bhavyanshu 很可能有一种预期的方法可以实现该结果,并且该方法是设计的private。只要你不知道为什么它是私有的,你就不应该解决这个问题。查看调用层次结构并查看调用该方法的位置,然后确定调用该私有方法的public 方法之一是否能够为您执行任务。然后使用它们。如果失败,请查看 jar 的来源以及原始代码是否在某个地方(或者您可以联系原始创建者)。他们让他们修复它。反思是最后的手段。
  • @AngeloNeuschitzer 好的,正如你刚才所说,有一个从 javascript 文件调用的公共函数。检查问题中的编辑。
【解决方案2】:

使用反射,您需要一个 BookView 实例来调用该方法(除非它是静态方法)。

BookView yourInstance = new BookView();
Method m = BookView.class.getDeclaredMethod("importBook");
m.setAccessible(true);//Abracadabra 
Boolean result = (Boolean) m.invoke(yourInstance, "A Path"); // pass your epubBookPath parameter (in this example it is "A Path"

你要找的方法是Method#invoke(Object, Object...)

【讨论】:

  • 此方法是否与 importBook() 作为私有函数一起使用?
  • @Hao 是的,setAccessible 允许这样做。
【解决方案3】:

使用反射获取方法并将Accessible设置为true然后使用BookView对象实例和所需参数(路径字符串)调用方法使用如下语句:

     Boolean result = (Boolean)method.invoke(bookObject, epubBookPath);

示例代码如下:

Method method = BookView.getDeclaredMethod("importBook");
method.setAccessible(true);
Boolean result = (Boolean)method.invoke(bookObject, epubBookPath);

【讨论】:

    【解决方案4】:

    私有方法不能在它定义的类之外被访问。 公开。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-17
      • 2013-02-15
      • 2014-01-27
      • 1970-01-01
      • 1970-01-01
      • 2018-11-08
      • 2016-10-22
      • 2013-08-03
      相关资源
      最近更新 更多