我试图调用一个方法,setPostal(String post)
我是从一个匿名类创建的,但由于某种原因,编译器甚至没有在main中识别它。这是什么原因?我的部分代码(地址是学生的内部类):
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();
}
}
答案 0 :(得分:2)
据推测,无论Address
是什么,它都没有setPostal(String)
方法。
在编译时,实例方法将根据调用它们的值的类型进行解析。
你正在调用它
test3.getAddress().setPostal("L1G 6h9") //Compiler: Cannot resolve symbol 'setPostal'
在类型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;
}
}
}.setPostal("whatever");
答案 1 :(得分:1)
表达式test3.getAddress()
的类型是Address
,这意味着您只能调用Address
类(或其超类型)中声明的方法。
编译器没有弄清楚在运行时,此表达式将评估为您的特殊匿名类的对象。编译器的工作不是为您运行程序,因此它可以计算出您可能使用的每个对象的类。因此,新方法setPostal
(似乎只存在于您的匿名类中)无法在此处使用。
答案 2 :(得分:1)
匿名课程是一个坏主意。尝试创建一个具体的类,然后实例化它。
您可以在课堂内声明这一点,以便将其隐藏在外面。
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
。
答案 3 :(得分:0)
对于那些得到的人:
“找不到符号” 。FUNCTION_NAME_HERE。
尝试动态使用匿名内部类时:
错误:错误:找不到符号“ myMethod”
Object t = new Object(){
public void myMethod(){
System.out.println("[METHOD]");
};;
};;
t.myMethod();
由于:
尽管存在方法,但您的匿名用户 对象向下转换为对象 没有方法。
错误:错误:找不到符号“ 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();
祝贺:
您正在动态创建一个类,其中只能有一个实例。
用法:函数中的小助手功能。