0 0

一个关于强制转换内部匿名类的错误5

现在有如下log
java.lang.ClassCastException: A cannot be cast to B$1

既然是匿名类,那么就不可以像下面这样转换
((B$1)o).method();


如何能制造出上面的这种异常,或者说如何能进行这样的类型转换
希望给个简单的示例

问题补充:log提示代码错误所在行是下面这样写的:
A a = (A)obj.method();
但是,如果这么写,log是不是应该是下面这样
B$1 cannot be cast to A
2012年9月26日 16:51

4个答案 按时间排序 按投票排序

0 0

上图了。

修改字节码之前 A$B



修改字节码之后A$1


你也可以下载 jbe([url]http://set.ee/jbe/[url])自行修改试试。

2012年9月29日 07:16
0 0

再详细给你解释下为什么不行: 比如
public class A {
   class B {
   }
}

Java语言定义引用内部类使用 A.B进行引用内部类B    即编写代码时必须通过外部类.内部类访问 不能外部类$内部类
编译之后B类其实是A$B.class

因此如果是
new B(){} 这种匿名内部类 在Java语言编写代码期间本身是没有名字的,那就无法在编写代码时引用这个类型,它只有在编译后才能确定是A$1 还是A$2。

比如如下你们内部类 将产生A$1.class (因为只有一个你们内部类)
public void test(final String s) {
      Object o = new A.B(){
     
          public void i() {
            String s2 = s;             
          }

      };
}

javap -verbose A$1 得到字节码

class A$1 extends A$B
final java.lang.String val$s; //就是那个s  即外部类的局部变量必须是final的,此处内部类会做拷贝
final A this$0;  //外部类
A$1(A, java.lang.String); //构造器

继续
   B d = (B)o;
产生的字节码是
   10:  aload_2
   11:  checkcast       #4; //class A$B    //检查o能不能转换为A$B  这是字节码层次
   14:  astore_3

即如果此处#4是 A$1  应该也是成功的  有时间修改下字节码试试(即语言层面无法做到你的需求 必须进行字节码的修改 但意义不大,还不如用反射调用呢)。
   B d = (B)o;
      d.say();

  15:  aload_3
  16:  invokevirtual   #5; //Method A$B.say:()V

调用类的包/protected/public方法通过invokevirtual完成, 此处如果调用匿名内部类自己的方法 可以考虑反射。


匿名内部类可以修改字节码完成,语言层面无法强制类型转换 而且如果非要调用匿名内部类内部的方法 可以通过反射完成。

  

2012年9月29日 06:38
0 0

obj 是 B的实例,如果:
class B {
    public Object method() {
        return new Object() {};
    }
}
这样,obj.method() 就会返回一个匿名内部类,有可能是B$1,后面强转 A 注定失败

2012年9月27日 10:11
0 0

B$1 是编译后的名字  而且这个名字可能因为你外部类中的匿名类的增加而增加

如Outer {

   void m() {
          new A(){}  //B$1
          new A(){}  //B$2
   }
}

外部类$数字 这个数字会随着匿名类的增加而变大  而且这是编译器行为 不同的编译器可能产生不同的$名字  

2012年9月26日 17:11

相关推荐

    MapReduce,泛型,匿名内部类,Runnable和Callable

    匿名内部类是在Java中定义一个新的类而无需为其命名的一种方式,通常用于实现接口或者继承类,并且只需要一次使用的情况。匿名内部类可以直接访问外部类的成员,包括final变量和局部变量。在多线程编程中,我们常常...

    day08面向对象-内部类、异常.doc

    匿名内部类必须继承一个父类或实现一个接口。 ##### 格式 ```java new 父类或者接口() { /* 执行代码 */ }; ``` ##### 示例 ```java class Outer { public void print() { new Runnable() { // 匿名内部类实现...

    7.内部类、泛型、递归、IO、异常.md

    这种内部类的一个显著特点是,它并不依赖于外部类的实例,也就是说,即使外部类没有实例化,静态内部类也可以被实例化。 ##### 示例 ```java public class OuterClass { // 静态内部类 public static class ...

    【05-面向对象(下)】

    •如果采用匿名内部类语法来创建函数式接口的实例,只要实现一个抽象方法即可,在这种情况下即可采用 Lambda表达式来创建对象,该表达式创建出来的对象的目标类型就是这个函数式接口。 •Lambda表达式有如下两...

    corejava面试题

    - `ClassCastException`:尝试将对象强制转换为不兼容类型时抛出。 - `ConcurrentModificationException`:当多线程并发修改集合时,可能抛出此异常。 - `NullPointerException`:当尝试访问或操作null对象引用时抛...

    笔试面试题.doc————电子版_doc版

    示例中创建了一个匿名内部类,并在`main`方法中实例化了外部类,输出显示了内部类和外部类的创建顺序。 6. 静态与非静态内部类: - 静态内部类(也称为嵌套类)可以访问外部类的静态成员,但不能访问非静态成员。...

    总结-Milo1

    - 匿名内部类:当需要快速实现一个简单的接口或父类时,可以使用匿名内部类,通常用在事件监听、线程创建等场景。 2. 抽象类与接口的选择: - 抽象类:当有多个类共享一部分代码,但是又存在一些共同的行为时,...

    JAVA面试题集1.doc

    - 匿名内部类没有名称,可以用来快速实现一个类或接口的功能。它可以继承一个类或实现一个接口,但只能在一个地方使用。 3. **Static Nested Class 和 Inner Class**: - 内部类(Inner Class)是嵌套在另一个类...

    Java面试题

    14. 强制类型转换与自动类型提升:在Java中,如果将一个较大的数值类型赋值给一个较小的数值类型,需要进行强制类型转换,否则可能会导致编译错误或数据丢失;而自动类型提升是指较小类型的数据在运算中自动转换为较...

    java面试题.pdf

    本文件是关于Java面试题的题目集合,涵盖了Java语言的多个核心知识点,包括但不限于访问修饰符、内部类、静态内部类、匿名内部类、集合框架、断言、字符串处理、数学函数、数据类型转换、静态方法、方法重载与覆盖、...

    java中的类.对象,接口

    内部类(inner class)是定义在另一个类内部的类,它可以访问外部类的所有成员,包括私有成员。匿名类则是在没有类名的情况下定义的类,通常用于快速创建一次性使用的对象,尤其是作为接口的实现。 异常类...

    2014年Java最全面试题以及答案.

    6. 一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 一个Java源文件中可以包含多个公共类(public class),但只能有一个公共类,并且文件名必须与该公共类的类名相同。如果一个源文件中没有...

    07-Java基础方面1

    以上是关于Java基础方面的知识详解,涵盖了作用域、匿名内部类、静态与非静态内部类、位运算符与逻辑运算符、集合框架、断言、字符串对象、方法重载与重写等多个重要概念。这些知识点是学习和理解Java编程的基础。

    文章分类:Java编程,java面试题1

    - 匿名内部类可以继承一个类或实现一个或多个接口。 - 匿名内部类通常用于实现简单的回调函数,例如监听器接口的实现。 ### Static Nested Class 和 Inner Class 的区别 3. **静态嵌套类(Static Nested Class)...

    WI TWO 淘宝分享Java面向对象编程(孙卫琴)_学习笔记

    8. 内部类:Java支持类的嵌套,包括成员内部类、局部内部类、匿名内部类和静态内部类。它们可以提高代码的封装性和可读性,但也会增加代码的复杂度。 9. 泛型:泛型是Java SE 5.0引入的新特性,用于在编译时检查...

    JAVA的核心技术:面向对象编程

    内部类是定义在另一个类内部的类,分为成员内部类、局部内部类、匿名内部类和静态内部类。它们提供了更灵活的封装和抽象,可以访问外部类的私有成员。 **9. 泛型** 泛型是Java 5引入的新特性,允许在类、接口和...

    java面试题大全.pdf

    - 可以,匿名内部类经常用来实现接口,特别是在需要快速定义一个接口实例的情况下非常有用。 #### 三、Static Nested Class 和 Inner Class 的不同 - **Static Nested Class(静态嵌套类)**: - 静态嵌套类(也...

    java面试题大全-基础方面.doc

    ` 错误,因为`short + int`的结果是`int`,需要强制转换。 - `s1 += 1;` 正确,编译器会自动处理类型转换。 10. **goto关键字**: - Java中`goto`是保留字,但未被使用,因此不能在代码中使用。 11. **length...

    java面向对象知识点

    内部类是定义在另一个类内部的类,它可以访问外部类的所有成员,包括私有成员。内部类分为成员内部类、局部内部类、匿名内部类和静态内部类。 9. 异常处理 Java提供了异常处理机制,通过try-catch-finally语句块...

Global site tag (gtag.js) - Google Analytics