您如何使用 ReflectionUtils 获取包私有 methods/fields?
How do you use ReflectionUtils to get package private methods/fields?
我试过像这样通过 Reflections 获取私有包 methods/field:
for (Method m : getAllMethods(cls, withModifier(Modifier.STATIC))){
但它是空的。有什么方法可以按包私有过滤吗?
要检索包私有方法,您需要查询所有方法并使用 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());
}
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");
}
}
我的测试class:
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
更新
如果你希望能够调用一个可访问的方法(例如 package-private),你将不得不这样:
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();
}
我试过像这样通过 Reflections 获取私有包 methods/field:
for (Method m : getAllMethods(cls, withModifier(Modifier.STATIC))){
但它是空的。有什么方法可以按包私有过滤吗?
要检索包私有方法,您需要查询所有方法并使用 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());
}
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");
}
}
我的测试class:
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
更新 如果你希望能够调用一个可访问的方法(例如 package-private),你将不得不这样:
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();
}