I'm not quite sure how to go about reflecting a class that only has package-level access. I know how to reflect any class that has public access, but I cannot figure out how to reflect the following example:
public func addActivityIndicatorToView(activityIndicator: UIActivityIndicatorView, view: UIView){
//activityIndicator configuration ...
activityIndicator.center = view.center
view.addSubview(activityIndicator)
activityIndicator.startAnimating()
}
======================
public class Main {
public static void main(String[] args) {
test t = new test();
Constructor<one.oneimpl> con = one.oneimpl.class.getDeclaredConstructor(test.class);
oneimpl o = con.newInstance(t);
o.doIt();
}
}
======================
package one;
// implementation class for mimicking android api
class oneimpl extends one {
Test mTest;
private oneimpl(test t){mTest = t;}
public void doIt(){System.out.println("Do It!");}
public void dontDoit(){System.out.println("Don't Do It!");}
}
======================
package one;
// abstract class for mimicking android api
abstract class one {
public void doIt();
public void dontDoIt();
}
As you can see, the class package one;
// empty class for mimicking android api
public class test {}
only has package-level access. This makes reflecting the class difficult for me. I continue to get compiler errors that states:
one
I've reviewed a few posts, to solve this on my own, but even after reading most of the "similar questions", reading the Main.java:4: error: oneimpl is not public in one; cannot be accessed from outside package
oneimpl o = con.newInstance(t);
api, and reading generic reflection procedures it's still unclear to me how to achieve this.
Ultimately what I am trying to do is to reflect particular portions of the API to build objects so that soot/spark can build a proper call graph. I'm not actually working inside the android API.
答案 0 :(得分:3)
您需要在每一步都使用反射,以便做您正在尝试做的事情。
首先,由于您无法从包外部直接引用包one
中的包范围类,因此您需要动态加载该类(还要注意{{1}的使用而不是直接使用?
):
oneimpl
然后你可以得到构造函数和Class<?> oneImplClass = Class.forName("one.oneimpl");
方法(确保你将这两个方法都设置为可访问,否则你会得到运行时错误):
doIt
接下来,实例化该类。由于您无法直接引用该类,因此您必须将其强制转换为Constructor<?> constructor = oneImplClass.getDeclaredConstructor(test.class);
constructor.setAccessible(true);
Method doIt = oneImplClass.getDeclaredMethod("doIt");
doIt.setAccessible (true);
:
Object
最后,您可以调用Object oneImpl = (Object) constructor.newInstance();
方法:
doIt
最后一点:在命名类时应遵循Java命名约定:doIt.invoke(oneImpl);
应为oneimpl
,OneImpl
应为test
。否则Test
之类的东西最终看起来像包名而不是完全限定的类名。
答案 1 :(得分:0)
.flush-bottom {
-fx-padding: 0.416667em 0.5em 0em 0.5em; /* 5 6 0 6 */
}