我試圖通過思考得到包私有方法/領域是這樣的:如何使用ReflectionUtils獲取包私有方法/字段?
for (Method m : getAllMethods(cls, withModifier(Modifier.STATIC))){
,但它是空的。有沒有什麼辦法可以通過私有包進行過濾?
我試圖通過思考得到包私有方法/領域是這樣的:如何使用ReflectionUtils獲取包私有方法/字段?
for (Method m : getAllMethods(cls, withModifier(Modifier.STATIC))){
,但它是空的。有沒有什麼辦法可以通過私有包進行過濾?
for (Method m : getAllMethods(cls, ReflectionUtils.getAllMethods(cls, Predicates.not(withModifier(Modifier.PRIVATE)), Predicates.not(withModifier(Modifier.PUBLIC)), Predicates.not(withModifier(Modifier.PROTECTED)))))
{
// DO STUFF
}
我用下面的方法來測試上述。 MyClass
包含5種方法;爲每個訪問修飾符和一個靜態:
public class MyClass
{
public void method1()
{
System.out.println("method1() invoked");
}
private void method2()
{
System.out.println("method2() invoked");
}
protected void method3()
{
System.out.println("method3() invoked");
}
void method4()
{
System.out.println("method4() invoked");
}
public static void method5()
{
System.out.println("method5() invoked");
}
}
我的測試類:
import static org.reflections.ReflectionUtils.withModifier;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Set;
import org.reflections.ReflectionUtils;
import accessmodifier.bar.MyClass;
import com.google.common.base.Predicates;
public class ReflectionTest
{
public static void main(String[] args)
{
Class<MyClass> cls = MyClass.class;
Set<Method> privateMethods = ReflectionUtils.getAllMethods(cls, withModifier(Modifier.PRIVATE));
Set<Method> protectedMethods = ReflectionUtils.getAllMethods(cls, withModifier(Modifier.PROTECTED));
Set<Method> publicMethods = ReflectionUtils.getAllMethods(cls, withModifier(Modifier.PUBLIC));
Set<Method> defaultMethods = ReflectionUtils.getAllMethods(cls, Predicates.not(withModifier(Modifier.PRIVATE)), Predicates.not(withModifier(Modifier.PUBLIC)), Predicates.not(withModifier(Modifier.PROTECTED)));
Set<Method> staticMethods = ReflectionUtils.getAllMethods(cls, withModifier(Modifier.STATIC));
System.out.println("Private Methods");
for (Method m : privateMethods)
System.out.println(m.getName());
System.out.println("\nProtected Methods");
for (Method m : protectedMethods)
System.out.println(m.getName());
System.out.println("\nPublic Methods");
for (Method m : publicMethods)
System.out.println(m.getName());
System.out.println("\nPackage-Private Methods");
for (Method m : defaultMethods)
System.out.println(m.getName());
System.out.println("\nStatic Methods");
for (Method m : staticMethods)
System.out.println(m.getName());
}
}
程序輸出
Private Methods
method2
Protected Methods
method3
Public Methods
method1
method5
Package-Private Methods
method4
Static Methods
method5
UPDATE 如果你想能夠調用一個可訪問的方法(比如package-private),你將不得不像th一樣是:
m.setAccessible(true); // bypass access
try
{
m.invoke(new MyClass(), null); // invoke method (you have to know parameter types and pass them if needed. Use *Method.getParameter...()* methods for that.
}
catch (IllegalAccessException | IllegalArgumentException
| InvocationTargetException e)
{
e.printStackTrace();
}
若要檢索您需要查詢所有方法和排除與public
,protected
或private
修飾這些方法包專用方法:
import org.reflections.ReflectionUtils;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Set;
...
Set<Method> allMethods = ReflectionUtils.getAllMethods(Foo.class);
for (Method method : allMethods) {
boolean isPackagePrivate = !(Modifier.isPrivate(method.getModifiers()) || Modifier.isPublic(method.getModifiers()) || Modifier.isProtected(method.getModifiers()));
if (isPackagePrivate) {
System.out.println("package private method: " + method.getName());
}
}
相同的字段:
Set<Field> allFields = ReflectionUtils.getAllFields(Foo.class);
for (Field field : allFields) {
boolean isPackagePrivate = !(Modifier.isPrivate(field.getModifiers()) || Modifier.isPublic(field.getModifiers()) || Modifier.isProtected(field.getModifiers()));
if (isPackagePrivate) {
System.out.println("package private field: " + field.getName());
}
}
com.google.guava:guava
提供了一個更方便以及使用Invokable的Method
(或Constructor
)附近的更易讀的API:
import com.google.common.reflect.Invokable
...
Invokable<?, Object> invokable = Invokable.from(method);
if (invokable.isPackagePrivate()) {
System.out.println("package private method: " + method.getName());
}
你只想要'private static'方法嗎?或者所有的「私人」方法?另外,你可以發佈你正在嘗試使用反射的類的方法簽名嗎? – JNYRanger 2015-03-22 20:10:11
包私有和私有訪問修飾符是**不**是同一件事。包私人是指那些不使用訪問修飾符;也稱爲Java中的默認修飾符。 – hfontanez 2015-03-22 20:43:56
在我以前的評論中,我的意思是說私有包和** STATIC **不是同一件事。 – hfontanez 2015-03-23 11:56:41