简体   繁体   中英

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:

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:

java: cannot find symbol symbol: method getFirstName() location: class 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.

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:

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 ?

You are using raw HashMap class, which treats keys and values as Objects. 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.

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. But generally, you can only access methods that are known to be on the compile time type of the reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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