-
一个关于强制转换内部匿名类的错误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 A2012年9月26日 16:51
4个答案 按时间排序 按投票排序
-
上图了。
修改字节码之前 A$B
修改字节码之后A$1
你也可以下载 jbe([url]http://set.ee/jbe/[url])自行修改试试。2012年9月29日 07:16
-
再详细给你解释下为什么不行: 比如
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
-
obj 是 B的实例,如果:
class B {
public Object method() {
return new Object() {};
}
}
这样,obj.method() 就会返回一个匿名内部类,有可能是B$1,后面强转 A 注定失败2012年9月27日 10:11
-
B$1 是编译后的名字 而且这个名字可能因为你外部类中的匿名类的增加而增加
如Outer {
void m() {
new A(){} //B$1
new A(){} //B$2
}
}
外部类$数字 这个数字会随着匿名类的增加而变大 而且这是编译器行为 不同的编译器可能产生不同的$名字2012年9月26日 17:11
相关推荐
匿名内部类是在Java中定义一个新的类而无需为其命名的一种方式,通常用于实现接口或者继承类,并且只需要一次使用的情况。匿名内部类可以直接访问外部类的成员,包括final变量和局部变量。在多线程编程中,我们常常...
匿名内部类必须继承一个父类或实现一个接口。 ##### 格式 ```java new 父类或者接口() { /* 执行代码 */ }; ``` ##### 示例 ```java class Outer { public void print() { new Runnable() { // 匿名内部类实现...
这种内部类的一个显著特点是,它并不依赖于外部类的实例,也就是说,即使外部类没有实例化,静态内部类也可以被实例化。 ##### 示例 ```java public class OuterClass { // 静态内部类 public static class ...
•如果采用匿名内部类语法来创建函数式接口的实例,只要实现一个抽象方法即可,在这种情况下即可采用 Lambda表达式来创建对象,该表达式创建出来的对象的目标类型就是这个函数式接口。 •Lambda表达式有如下两...
- `ClassCastException`:尝试将对象强制转换为不兼容类型时抛出。 - `ConcurrentModificationException`:当多线程并发修改集合时,可能抛出此异常。 - `NullPointerException`:当尝试访问或操作null对象引用时抛...
示例中创建了一个匿名内部类,并在`main`方法中实例化了外部类,输出显示了内部类和外部类的创建顺序。 6. 静态与非静态内部类: - 静态内部类(也称为嵌套类)可以访问外部类的静态成员,但不能访问非静态成员。...
- 匿名内部类:当需要快速实现一个简单的接口或父类时,可以使用匿名内部类,通常用在事件监听、线程创建等场景。 2. 抽象类与接口的选择: - 抽象类:当有多个类共享一部分代码,但是又存在一些共同的行为时,...
- 匿名内部类没有名称,可以用来快速实现一个类或接口的功能。它可以继承一个类或实现一个接口,但只能在一个地方使用。 3. **Static Nested Class 和 Inner Class**: - 内部类(Inner Class)是嵌套在另一个类...
14. 强制类型转换与自动类型提升:在Java中,如果将一个较大的数值类型赋值给一个较小的数值类型,需要进行强制类型转换,否则可能会导致编译错误或数据丢失;而自动类型提升是指较小类型的数据在运算中自动转换为较...
本文件是关于Java面试题的题目集合,涵盖了Java语言的多个核心知识点,包括但不限于访问修饰符、内部类、静态内部类、匿名内部类、集合框架、断言、字符串处理、数学函数、数据类型转换、静态方法、方法重载与覆盖、...
内部类(inner class)是定义在另一个类内部的类,它可以访问外部类的所有成员,包括私有成员。匿名类则是在没有类名的情况下定义的类,通常用于快速创建一次性使用的对象,尤其是作为接口的实现。 异常类...
6. 一个".java"源文件中是否可以包括多个类(不是内部类)?有什么限制? 一个Java源文件中可以包含多个公共类(public class),但只能有一个公共类,并且文件名必须与该公共类的类名相同。如果一个源文件中没有...
以上是关于Java基础方面的知识详解,涵盖了作用域、匿名内部类、静态与非静态内部类、位运算符与逻辑运算符、集合框架、断言、字符串对象、方法重载与重写等多个重要概念。这些知识点是学习和理解Java编程的基础。
- 匿名内部类可以继承一个类或实现一个或多个接口。 - 匿名内部类通常用于实现简单的回调函数,例如监听器接口的实现。 ### Static Nested Class 和 Inner Class 的区别 3. **静态嵌套类(Static Nested Class)...
8. 内部类:Java支持类的嵌套,包括成员内部类、局部内部类、匿名内部类和静态内部类。它们可以提高代码的封装性和可读性,但也会增加代码的复杂度。 9. 泛型:泛型是Java SE 5.0引入的新特性,用于在编译时检查...
内部类是定义在另一个类内部的类,分为成员内部类、局部内部类、匿名内部类和静态内部类。它们提供了更灵活的封装和抽象,可以访问外部类的私有成员。 **9. 泛型** 泛型是Java 5引入的新特性,允许在类、接口和...
- 可以,匿名内部类经常用来实现接口,特别是在需要快速定义一个接口实例的情况下非常有用。 #### 三、Static Nested Class 和 Inner Class 的不同 - **Static Nested Class(静态嵌套类)**: - 静态嵌套类(也...
` 错误,因为`short + int`的结果是`int`,需要强制转换。 - `s1 += 1;` 正确,编译器会自动处理类型转换。 10. **goto关键字**: - Java中`goto`是保留字,但未被使用,因此不能在代码中使用。 11. **length...
内部类是定义在另一个类内部的类,它可以访问外部类的所有成员,包括私有成员。内部类分为成员内部类、局部内部类、匿名内部类和静态内部类。 9. 异常处理 Java提供了异常处理机制,通过try-catch-finally语句块...