Tag: reflection

从调用返回另一个代理的Java.lang.reflect.Proxy在赋值时导致ClassCastException

所以我正在玩geotools,我想我会代理他们的一个数据访问类,并跟踪它们在代码中的使用方式。 我编写了一个动态代理并在其中包含了一个FeatureSource(接口),然后快乐地完成了它。 然后我想看一下featureSource返回的一些传递对象,因为FeatureSource做的主要事情是返回一个FeatureCollection(FeatureSource类似于sql DataSource和featurecollection到sql语句)。 在我的invocationhandler中,我只是将调用传递给底层对象,打印出目标类/方法/ args并导致结果,但是对于返回FeatureCollection(另一个接口)的调用,我将该对象包装在我的代理中(相同的类,但一个新的实例,应该不重要吗?)并返回它。 BAM! Classcastexception: java.lang.ClassCastException: $Proxy5 cannot be cast to org.geotools.feature.FeatureCollection at $Proxy4.getFeatures(Unknown Source) at MyClass.myTestMethod(MyClass.java:295) 调用代码: FeatureSource featureSource = … // create the FS featureSource = (FeatureSource) FeatureSourceProxy.newInstance(featureSource, features); featureSource.getBounds();// ok featureSource.getSupportedHints();// ok DefaultQuery query1 = new DefaultQuery(DefaultQuery.ALL); FeatureCollection results = featureSource.getFeatures(query1); //<- explosion here 代理人: public class FeatureSourceProxy implements […]

如何通过反思防止访问?

在Java文档中,它提到使用f.setAccessible(true)方法我们可以违反封装的原则。 但是,如果我正在编写任何具有完全安全性的类,例如使用私有变量,我怎样才能防止它被reflection访问? 例如,我有一个具有完整安全实例变量的类: public final class Immutable { private final int someVal; public Immutable(int someVal) { this.someVal = someVal; } public int getVal() { return someVal; } } 但我可以使用这样的reflection修改该实例变量: public class Tester { public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { Immutable i = new Immutable(10); // output 10 System.out.println(i.getVal()); Field f […]

JUnit 4和Suspend-on-Exception

当我的代码中抛出未捕获的exception时,我习惯让调试器停止在throw语句中,这样我就可以检查局部变量以及抛出exception时所涉及的所有对象的成员。 使用IntelliJ Idea,可以通过转到“运行” ,“ 查看断点” ,选择“ exception断点”选项卡,选中“ 任何exception ”并确保未选中“ 捕获exception”复选框,同时选中“ 未捕获exception”复选框来完成此操作。 使用Eclipse和Visual Studio (对于C#),它是不同的,但是沿着相同的路线。 使调试器以这种方式运行的能力非常有用; 实际上非常有用,我相应地构建了我的程序的主循环:在发布版本中,主循环当然嵌入在try-catch-all中; 但是在调试版本中,主循环中没有try-catch块,因此在程序中任何地方都没有捕获的任何exception都将保持未被捕获状态,因此调试器将在抛出它们时暂停我的程序。 但是,在使用JUnit测试我的Java类时,我遇到了一个问题:调试器不会停止任何exception。 相反,会发生的事情是,不仅预期的,而且意外的exception也会被自动捕获,并且我会获得一个事后exception堆栈跟踪以尝试理解。 那不是很酷。 我曾经认为这种情况正在发生,因为JUnit使用java.lang.reflect.Method.invoke() ,它捕获所有exception并将它们转换为TargetInvocationExceptions ,但后来我编写了自己的自定义JUnit运行器,它知道我的测试类个人直接调用其方法而不使用Method.invoke() ,问题仍然存在。 这意味着问题出现在核心JUnit中。 那么,其他人是否也有同样的问题? 有没有人知道一个解决方案,以便我们可以让调试器在使用JUnit进行测试时暂停程序执行意外exception? 相关(未回答)问题: 在Eclipse Junit测试运行器中暂停未捕获的运行时exception 相关(未答复)的问题: 如何在jUnit测试用例中进入调试器? 相关(部分回答)问题: 使用jUnit打破Eclipse中的exception (接受的答案说“如果你在jUnit中调试单个方法,断点就会开始工作。如果在jUnit中调试整个类或包,调试器不会不行。“)

用于测试私有方法的Java工具?

对私有方法测试的意义有不同的看法,例如, 这里和这里 。 我个人认为这是有道理的,问题是如何正确地做到这一点。 在C ++中你可以使用#define hack或者使测试类成为friend ,在C#中有InternalsVisibleToAttribute ,但是在Java中我们必须使用reflection或使它们“可见以进行测试”并对它们进行注释以便使它们成为可能 。意图清楚。 两者的缺点应该非常清楚。 我认为应该有更好的东西。 从…开始 public class Something { private int internalSecret() { return 43; } } 能够在测试代码中调用私有方法会很好 @MakeVisibleForTesting Something something = new Something(); Assert.assertEquals(43, something.internalSecret()); 这里的注释会使用reflection静默地将所有调用转换为something私有方法。 我想知道龙目岛是否可以做到(并会问作者)。 做这么多魔术很可能certificate太复杂了,无论如何它需要一些时间,所以我正在寻找一些替代方案。 也许用@Decapsulate注释正在测试的类,并使用注释处理器生成类Decapsulated_Something看起来像 public class Decapsulated_Something { public Decapsulated_Something(Something delegate) { this.delegate = delegate } public boolean internalSecret() { // […]

reflection如何影响Perm的大小?

我理解perm大小用于存储元数据,包括字节代码,静态东西等。 我的问题是如何使用reflection影响烫发大小。 我的意思是如果Program-A使用正常的运行对象方式而Program-B全部使用reflection, 那么两个程序的perm大小将如何比较 ?

是否可以使用Reflection迭代包内的所有类?

我有一个有一些价值的字符串。 我想迭代调用特定方法的包中的所有类,如果方法返回的值等于我的String中的值,则创建该类的对象。 我想以动态方式执行此操作,因此如果我在此包中添加一个类,它将自动进行迭代。 这可能吗? 如果没有,有办法做我想要的吗? 我期待着类似的东西。 for(Class clazz: SomeClass.listClasses(“org.package”)){ //code here }

Java中的可变字符串

几乎每个人都知道Java中的字符串是不可变的。 最近我发现了一些可能暗示它并不总是正确的东西。 我们试试这段代码吧: System.out.println(“——– BEFORE MODIFICATIONS ——–“); String beforeTest = new String(“Original”); System.out.println(beforeTest); java.lang.reflect.Field valueField = String.class.getDeclaredField(“value”); valueField.setAccessible(true); valueField.set(“Original”, “Modified”.toCharArray()); System.out.println(“——– AFTER MODIFICATIONS ——–“); System.out.println(beforeTest); System.out.println(“Original”); String test = new String(“Original”); System.out.println(test); String test2 = new String(“Original 2”); System.out.println(test2); 输出将是: ——– BEFORE MODIFICATIONS ——– Original ——– AFTER MODIFICATIONS ——– Original Modified Modified Original 2 这个技巧如何运作? […]

Class.getFields()返回的字段顺序

Class.getFields() Javadoc说:“返回的数组中的元素没有排序,也没有任何特定的顺序。” 有关如何确定订单的任何提示? 有可能当我执行两次这个方法时,我得到不同顺序的字段吗? 换句话说,对于给定的编译类,或者甚至在相同源文件的编译之间,顺序是否稳定?

在同一个包中访问私有内部类

我有两个编译单元: public class OuterClass{ private static class InnerClass{ public String test(){ return “testing123”; } } public static void main( String[] args ){ new CallingClass().test( new InnerClass() ); } } public class CallingClass{ public void test( Object o ){ try{ Method m = o.getClass().getMethod( “test” ); Object response = m.invoke( o ); System.out.println( “response: ” + […]

如何使用给定的注释运行所有方法?

这就是我想要发生的事情: public class MainClass { public static void main(String args[]) { run @mod(); // run all methods annotated with @mod annotation } } 注释声明: @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface mod { String name() default “”; } 要调用的方法 : public class Good { @mod (name = “me1”) public void calledcs(){ System.out.println(“called”); } @mod (name = “me2”) public […]