无法调用匿名 Class 方法
Cannot call an Anonymous Class Method
我正在尝试调用一个方法,setPostal(String post)
我从一个匿名 class 生成的,但出于某种原因,编译器甚至无法在 main 中识别它。这是什么原因?我的部分代码(地址是Student的内部class):
学生
public class Student implements Gradeable, Cloneable {
String name;
int id;
Address address;
public Student() {
name = "unknown";
address = new Address();
}
public Student(String name, int id, Integer... option) {
this.name = name;
this.id = id;
if (option.length > 0) {
if (option[0] > 0) {
address = new Address() {
String postal;
public void setPostal(String post) {
postal = post;
}
@Override
public String toString() {
return "Street: " + street + " | number: " + number
+ " | town: " + town + " | province: " + province
+ " | Postal Code: " + postal;
}
};
}
} else {
address = new Address();
}
}
Address getAddress() {
return address;
}
void setAddress(Address address) {
this.address = address;
}
public static void main(String[] args) throws CloneNotSupportedException, InterruptedException {
Student test = new Student("ryan", 41254, 1);
test.getAddress().setPostal("L1G 6h9") // Compiler: Cannot resolve symbol 'setPostal'
}
}
地址
public class Address implements Cloneable {
String street;
int number;
String town;
String province;
String zip;
public Address() {
}
public Address(String street, int number, String town,
String province, String zip) {
this.street = street;
this.number = number;
this.town = town;
this.province = province;
this.zip = zip;
}
String getStreet() {
return street;
}
int getNumber() {
return number;
}
String getTown() {
return town;
}
String getProvince() {
return province;
}
String getZip() {
return zip;
}
@Override
public String toString() {
return "Street: " + street + " | number: " + number
+ " | town: " + town + " | province: " + province
+ " | ZIP: " + zip;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Address)
if (((Address) obj).getStreet().equals(street)
&& ((Address) obj).getNumber() == number
&& ((Address) obj).getTown().equals(town)
&& ((Address) obj).getProvince().equals(province)
&& ((Address) obj).getZip().equals(zip)){
System.out.println("Address equal");
return true;
}
System.out.println("Address not equal");
return false;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
据推测,无论 Address
是什么,它都没有 setPostal(String)
方法。
实例方法在编译时根据调用它们的值的类型进行解析。
你正在调用它
test3.getAddress().setPostal("L1G 6h9") //Compiler: Cannot resolve symbol 'setPostal'
在 Address
类型的表达式上,它没有这样的方法,不管子类型(匿名子 class)是否有。
调用仅在匿名 class 中声明的方法的唯一方法(减去反射)是在匿名 class 实例创建表达式返回的值上调用该方法。
new Address() {
String postal;
public void setPostal(String post) {
postal = post;
}
@Override
public String toString() {
return "Street: " + street + " | number: " + number
+ " | town: " + town + " | province: " + province
+ " | Postal Code: " + postal;
}
}
}.setPostal("whatever");
表达式 test3.getAddress()
的类型是 Address
,这意味着您只能调用在 Address
class(或其超类型)中声明的方法).
编译器没有弄清楚在 运行 时,这个表达式将计算为您的特殊匿名 class 的对象。为您 运行 您的程序不是编译器的工作,因此它可以计算出您可能使用的每个对象的 class 。所以新方法setPostal
(貌似只存在于你的匿名class)不能在这里使用。
匿名 classes 是个坏主意。尝试创建一个具体的 class,然后实例化它。
您可以在您的 class 中声明它以从外部隐藏它。
public class Student implements Gradeable, Cloneable {
// ...
private static class PostalAddress extends Address {
String postal;
public PostalAddress {
super();
}
public void setPostal(String post) {
postal = post;
}
@Override
public String toString() {
return "Street: " + street + " | number: " + number
+ " | town: " + town + " | province: " + province
+ " | Postal Code: " + postal;
}
}
// ...
}
那就用吧
public Student(String name, int id, Integer... option) {
this.name = name;
this.id = id;
if (option.length > 0) {
if (option[0] > 0) {
address = new PostalAddress();
}
} else {
address = new Address();
}
}
那么你所要做的就是将地址转换为test
。
public static void main(String[] args) throws CloneNotSupportedException, InterruptedException{
Student test = new Student("ryan", 41254, 1);
((PostalAddress) test.getAddress()).setPostal("L1G 6h9");
}
注意: 如果 option.length > 0
但 option[0] <= 0
,您的 address
对象将是 null
.
获得者:
"Cannot find symbol" FUNCTION_NAME_HERE.
尝试使用 匿名内部 class 时:
WRONG: 错误: 找不到符号 "myMethod"
Object t = new Object(){
public void myMethod(){
System.out.println("[METHOD]");
};;
};;
t.myMethod();
因为:
虽然方法存在,但是你的匿名
object 被向下转换为 Object,它
没有方法。
WRONG: 错误: 找不到符号 "myMethod"
class Test{};
Test t = new Test(){
public void myMethod(){
System.out.println("[METHOD]");
};;
};;
t.myMethod();
因为:
同上一个原因。
(但我们走在正确的轨道上。)
正确:
abstract class Test{ abstract public void myMethod(); }
Test t = new Test(){
public void myMethod(){
System.out.println("[METHOD]");
};;
};;
t.myMethod();
恭喜:
您即时创建了一个 class,其中只能有一个实例。
用法:函数中的小辅助函数。
我正在尝试调用一个方法,setPostal(String post)
我从一个匿名 class 生成的,但出于某种原因,编译器甚至无法在 main 中识别它。这是什么原因?我的部分代码(地址是Student的内部class):
学生
public class Student implements Gradeable, Cloneable {
String name;
int id;
Address address;
public Student() {
name = "unknown";
address = new Address();
}
public Student(String name, int id, Integer... option) {
this.name = name;
this.id = id;
if (option.length > 0) {
if (option[0] > 0) {
address = new Address() {
String postal;
public void setPostal(String post) {
postal = post;
}
@Override
public String toString() {
return "Street: " + street + " | number: " + number
+ " | town: " + town + " | province: " + province
+ " | Postal Code: " + postal;
}
};
}
} else {
address = new Address();
}
}
Address getAddress() {
return address;
}
void setAddress(Address address) {
this.address = address;
}
public static void main(String[] args) throws CloneNotSupportedException, InterruptedException {
Student test = new Student("ryan", 41254, 1);
test.getAddress().setPostal("L1G 6h9") // Compiler: Cannot resolve symbol 'setPostal'
}
}
地址
public class Address implements Cloneable {
String street;
int number;
String town;
String province;
String zip;
public Address() {
}
public Address(String street, int number, String town,
String province, String zip) {
this.street = street;
this.number = number;
this.town = town;
this.province = province;
this.zip = zip;
}
String getStreet() {
return street;
}
int getNumber() {
return number;
}
String getTown() {
return town;
}
String getProvince() {
return province;
}
String getZip() {
return zip;
}
@Override
public String toString() {
return "Street: " + street + " | number: " + number
+ " | town: " + town + " | province: " + province
+ " | ZIP: " + zip;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Address)
if (((Address) obj).getStreet().equals(street)
&& ((Address) obj).getNumber() == number
&& ((Address) obj).getTown().equals(town)
&& ((Address) obj).getProvince().equals(province)
&& ((Address) obj).getZip().equals(zip)){
System.out.println("Address equal");
return true;
}
System.out.println("Address not equal");
return false;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
据推测,无论 Address
是什么,它都没有 setPostal(String)
方法。
实例方法在编译时根据调用它们的值的类型进行解析。
你正在调用它
test3.getAddress().setPostal("L1G 6h9") //Compiler: Cannot resolve symbol 'setPostal'
在 Address
类型的表达式上,它没有这样的方法,不管子类型(匿名子 class)是否有。
调用仅在匿名 class 中声明的方法的唯一方法(减去反射)是在匿名 class 实例创建表达式返回的值上调用该方法。
new Address() {
String postal;
public void setPostal(String post) {
postal = post;
}
@Override
public String toString() {
return "Street: " + street + " | number: " + number
+ " | town: " + town + " | province: " + province
+ " | Postal Code: " + postal;
}
}
}.setPostal("whatever");
表达式 test3.getAddress()
的类型是 Address
,这意味着您只能调用在 Address
class(或其超类型)中声明的方法).
编译器没有弄清楚在 运行 时,这个表达式将计算为您的特殊匿名 class 的对象。为您 运行 您的程序不是编译器的工作,因此它可以计算出您可能使用的每个对象的 class 。所以新方法setPostal
(貌似只存在于你的匿名class)不能在这里使用。
匿名 classes 是个坏主意。尝试创建一个具体的 class,然后实例化它。
您可以在您的 class 中声明它以从外部隐藏它。
public class Student implements Gradeable, Cloneable {
// ...
private static class PostalAddress extends Address {
String postal;
public PostalAddress {
super();
}
public void setPostal(String post) {
postal = post;
}
@Override
public String toString() {
return "Street: " + street + " | number: " + number
+ " | town: " + town + " | province: " + province
+ " | Postal Code: " + postal;
}
}
// ...
}
那就用吧
public Student(String name, int id, Integer... option) {
this.name = name;
this.id = id;
if (option.length > 0) {
if (option[0] > 0) {
address = new PostalAddress();
}
} else {
address = new Address();
}
}
那么你所要做的就是将地址转换为test
。
public static void main(String[] args) throws CloneNotSupportedException, InterruptedException{
Student test = new Student("ryan", 41254, 1);
((PostalAddress) test.getAddress()).setPostal("L1G 6h9");
}
注意: 如果 option.length > 0
但 option[0] <= 0
,您的 address
对象将是 null
.
获得者:
"Cannot find symbol" FUNCTION_NAME_HERE.
尝试使用 匿名内部 class 时:
WRONG: 错误: 找不到符号 "myMethod"
Object t = new Object(){
public void myMethod(){
System.out.println("[METHOD]");
};;
};;
t.myMethod();
因为:
虽然方法存在,但是你的匿名 object 被向下转换为 Object,它 没有方法。
WRONG: 错误: 找不到符号 "myMethod"
class Test{};
Test t = new Test(){
public void myMethod(){
System.out.println("[METHOD]");
};;
};;
t.myMethod();
因为:
同上一个原因。 (但我们走在正确的轨道上。)
正确:
abstract class Test{ abstract public void myMethod(); }
Test t = new Test(){
public void myMethod(){
System.out.println("[METHOD]");
};;
};;
t.myMethod();
恭喜:
您即时创建了一个 class,其中只能有一个实例。
用法:函数中的小辅助函数。