简体   繁体   English

如何确定一个类名所指示的内部匿名类?

[英]how to figure out which inner anonymous class indicated by a class name?

I used MAT tool in Eclipse to investigate a memory leak issue. 我在Eclipse中使用MAT工具来研究内存泄漏问题。 I found that the leak was caused by an anonymous inner class instance in my app. 我发现泄漏是由我的应用程序中的匿名内部类实例引起的。 The class name displayed in MAT is com.mycompany.myproduct.MyActivity$3. MAT中显示的类名是com.mycompany.myproduct.MyActivity $ 3。 There are many anonymous inner classes defined in MyActivity.java. MyActivity.java中定义了许多匿名内部类。 How do I know the which inner class com.mycompany.myproduct.MyActivity$3 indicates? 我怎么知道com.mycompany.myproduct.MyActivity $ 3指示哪个内部类?

Thanks. 谢谢。

On the Oracle compiler, they're numbered in order of occurrence in the class. 在Oracle编译器上,它们按类中的出现顺序编号。 I'm not sure if that's part of any specification or consistent with other implementations. 我不确定这是否是任何规范的一部分或与其他实现一致。

You could decompile the class-- JD-GUI is a great tool for that--and then you'll see what you want to know. 你可以反编译这个类 - JD-GUI是一个很好的工具 - 然后你会看到你想知道的。 You could even just go with basic disassembly using javap -c . 你甚至可以使用javap -c进行基本的反汇编。 It'll give you a rough idea of where the classes occur. 它会让你大致了解类的出现位置。

Hint: debugger somehow knows which classes are where. 提示:调试器以某种方式知道哪些类在哪里。 So you can, too! 所以你也可以!

Try using javap on this example with two anonymous classes: 尝试在这个例子中使用javap和两个匿名类:

import java.util.*;

public class Test {
    public static void main(String [] args) {
        Map m = new HashMap(){{System.out.print(1);}};
        Map m1 = new HashMap(){{System.out.print(2);}};
    }
}

Compile it and run javap -c -l : 编译它并运行javap -c -l

$ javap -c -l Test
Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

  LineNumberTable: 
   line 3: 0



public static void main(java.lang.String[]);
  Code:
   0:   new #2; //class Test$1
   3:   dup
   4:   invokespecial   #3; //Method Test$1."<init>":()V
   7:   astore_1
   8:   new #4; //class Test$2
   11:  dup
   12:  invokespecial   #5; //Method Test$2."<init>":()V
   15:  astore_2
   16:  return

  LineNumberTable: 
   line 5: 0
   line 7: 8
   line 9: 16



}

As you can see, the first class got name Test$1 , the second one— Test$2 . 正如您所看到的,第一个类名为Test$1 ,第二个名为Test$2 Hope tat helps. 希望有帮助。

For more specific information, decompile the specific classes you're interested in, eg javap -c -l Test\\$2 . 有关更具体的信息,请反编译您感兴趣的特定类,例如javap -c -l Test\\$2 Pay attention to line numbers: they will give you a hint on where in the source file the class was defined. 注意行号:它们会给你一个关于源文件中定义类的位置的提示。

When you compile your code securely you have MyActivity$1.class, MyActivity$2.class, MyActivity$3.class, and so on. 当您安全地编译代码时,您有MyActivity $ 1.class,MyActivity $ 2.class,MyActivity $ 3.class,等等。 You can use a java decompiler (over your .class) in order to identify the anonymus class that is throwing the exception. 您可以使用java反编译器(通过.class)来识别抛出异常的anonymus类。

The whole point of anonymous classes is that they are just that. 匿名类的重点在于它们就是这样。 As you have found its not easy to figure out which one its come from. 正如你发现它不容易弄清楚它来自哪一个。 Usually the numbering starts at one, so my guess is that it will be the third declared anonymous class that is your problem. 通常编号从一开始,所以我的猜测是它将是第三个声明的匿名类,这是你的问题。

In this situation, you maybe better off to refactor your code to not have any anonymous classes. 在这种情况下,您最好重构代码以避免任何匿名类。 Otherwise I suggest attaching the debugger and stepping the code. 否则我建议附加调试器并踩代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM