简体   繁体   English

Java Map怪异的行为

[英]Java Map weird behaviour

I was about to try something out in Java and came onto the following issue, before I explain everything here is my code: 在解释这里所有内容都是我的代码之前,我将尝试使用Java进行尝试并遇到以下问题:

Main class: 主班:

package com.company;

import java.util.HashMap;

public class Main {

    public static void main(String[] args) {
        // write your code here

        HashMap lol = new HashMap();

        Student david = new Student("David", "Shite");

        lol.put("First:", david);

        System.out.println("HashMap key: " + lol.keySet());
        System.out.println("Value of the key: " + lol.get("First:"));
        System.out.println("Student's first and last name: " + 
((Student)lol.get("First:")).getFirstName());

    }
}

Student class: 学生班:

class Student {

    private String firstName;
    private String lastName;

    public Student(String firstName, String lastName){
        this.firstName = firstName;
        this.lastName = lastName;
     }

    public String getFirstName(){
        return this.firstName;
     }

    public String getLastName() {
        return this.lastName;
     }
 }

My question is regarding this line of code: 我的问题是关于以下代码行:

System.out.println("Student's first and last name: " + 
    ((Student)lol.get("First:")).getFirstName());

This works, but at first I tried this: 这行得通,但是起初我尝试了这个:

System.out.println("Student's first and last name: " + 
                (lol.get("First:").getFirstName()));

The code above didn't work as it (IntelliJ) didn't recognize the method "getFirstName()", with the following error: 上面的代码不起作用,因为它(IntelliJ)无法识别方法“ getFirstName()”,并出现以下错误:

java: cannot find symbol symbol: method getFirstName() location: class java.lang.Object java:找不到符号symbol:方法getFirstName()位置:类java.lang.Object

After that I tried casting it and it would work, but I'm unsure as why it doesn't work without casting when the value that is put into HashMap was object of type Student, and getFirstName() is valid getter method inside the mentioned class. 之后,我尝试进行强制转换,并且可以正常工作,但是我不确定为什么当放入HashMap的值是Student类型的对象并且getFirstName()是上述提及的有效getter方法时,如果不强制转换就无法正常工作类。

I also tried this in order to ensure that it was really still instance of Student class and wasn't converted implicitly to Object class: 为了确保它实际上仍然是Student类的实例,并且没有被隐式转换为Object类,我也进行了尝试:

System.out.println(lol.get("First:") instanceof Student);

and

System.out.println(lol.get("First:").getClass());

and output was true for the first statement and "class com.company.Student" for the second one, so can someone explain why it doesn't recognize the getter method call without explicitly casting the return value to Student class ? 并且对于第一个语句,输出为true,对于第二个语句,输出为true,那么有人可以解释一下为什么在不将返回值显式转换为Student类的情况下无法识别getter方法调用的原因吗?

You are using raw HashMap class, which treats keys and values as Objects. 您正在使用原始HashMap类,该类将键和值视为对象。 In order to make it recognize Students, you should use 为了使其能够识别学生,您应该使用

HashMap<String, Student> lol = new HashMap<>();

There shouldn't be anything surprising about this. 对此应该没有任何惊奇。 The object must be explicitly referenced by a variable of type Foo before you can use Foo methods. 该对象必须通过类型的变量明确提到Foo ,然后才能使用Foo方法。

You can see this for yourself here: 您可以在这里自己看到:

Student david = new Student("David", "Shite");
Object object = david;
object.getFirstName(); // won't work

If you used generics properly, eg Map<String, Student> lol = new HashMap<>() , that would have solved the issue. 如果您正确使用了泛型,例如Map<String, Student> lol = new HashMap<>() ,那将解决此问题。 But generally, you can only access methods that are known to be on the compile time type of the reference. 但是通常,您只能访问已知在引用的编译时类型上的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM