为何MyConsumer<String> implements Consumer<String>会引发Java编译错误?
编译错误原因解析
错误代码示例
class MyConsumer<String> implements Consumer<String>{ @Override public void accept(String s){ System.out.println("hello".toUpperCase()); System.out.println(s.toUpperCase()); } }
错误信息
ConsumerTest.java:22: error: cannot find symbol
System.out.println(s.toUpperCase());
^
symbol: method toUpperCase()
location: variable s of type String
where String is a type-variable:
String extends Object declared in class MyConsumer
正确代码示例
class MyConsumer implements Consumer<String>{ @Override public void accept(String s){ System.out.println("hello".toUpperCase()); System.out.println(s.toUpperCase()); } }
差异原因
核心问题出在类定义的泛型声明上:
- 错误代码里的
class MyConsumer<String>,这里的<String>是自定义的泛型类型参数,它只是一个占位符(和常用的T、E作用完全一样),默认继承自Object。这会把Java自带的java.lang.String类给"遮蔽"掉,导致代码里所有的String都指向这个泛型参数,而不是真正的字符串类。
所以accept方法里的参数s是Object类型的子类,Object没有toUpperCase()方法,编译自然报错。而"hello"是字面量,属于真正的java.lang.String,所以它的方法能正常调用。 - 正确代码去掉了类名后的
<String>,此时Consumer<String>里的String就是Java标准库的java.lang.String类,accept方法的参数s也是这个字符串类型,调用toUpperCase()完全符合语法,因此没有编译错误。
内容的提问来源于stack exchange,提问作者Ali
相关产品推荐
相关产品推荐

