Создание внутреннего класса - PullRequest
44 голосов
/ 01 ноября 2010

Я работаю над примером проблемы переопределения hashCode и метода equals, но получаю ошибку: " Нет доступного экземпляра типа CustomHashCodeExample. Необходимо квалифицировать выделение с включающим экземпляром типа CustomHashCodeExample (например, Axnew A () где x - это экземпляр CustomHashCodeExample)." Я написал внутренний класс HashPerson и получаю эту ошибку, когда пытаюсь создать экземпляр этого внутреннего класса в другом методе с именем testHashCodeOverride ().

public static void testHashCodeOverride(){   
    System.out.println("\nTest HashCode Override Method");
    System.out.println("==================================\n");

    HashPerson william = new HashPerson("willy");
    HashPerson bill = new HashPerson("willy");          
}

Этот код работает нормально, хотя я не вижу статический внутренний класс или создание экземпляра внешнего класса, запутался: (

public class HashCodeExample {

    public static void testHashCodeOverride() {

        HashPerson william = new HashPerson("Willy");
        HashPerson bill = new HashPerson("Willy");
        System.out.println("Hash code for william  = " + william.hashCode());
        System.out.println("Hash code for bill     = " + bill.hashCode());

        HashMap table = new HashMap();
        table.put(william, "Silly");

        if (table.containsKey(william)) {
            System.out.println(table.get(william));
        } else {
            System.out.println("Key " + william + " not found");
        }

        if (table.containsKey(bill)) {
            System.out.println(table.get(bill));
        } else {
            System.out.println("Key " + bill + " not found");
        }


    }

    class HashPerson {
        private static final int HASH_PRIME = 1000003;

        public HashPerson(String name) {
            this.name = name;
        }

        public String toString() {
            return name;
        }

        public boolean equals(Object rhs) {
            if (this == rhs)
                return true;

            // make sure they are the same class
            if (rhs == null || rhs.getClass() != getClass())
                return false;

            // ok, they are the same class. Cast rhs to HashPerson
            HashPerson other = (HashPerson) rhs;

            // our test for equality simply checks the name field
            if (!name.equals(other.name)) {
                return false;
            }

            // if we get this far, they are equal
            return true;
        }
        public int hashCode() {
            int result = 0;
            result = HASH_PRIME * result + name.hashCode();
            return result;
        }
        private String name;

    }
}

Ответы [ 2 ]

125 голосов
/ 01 ноября 2010

Я думаю, вы хотите объявить класс HashPerson как static.В противном случае его можно создать только в контексте содержащего класса, либо в методе содержащего класса, либо с использованием кода, подобного следующему:

ContainingClass container = new ContainingClass();
HashPerson william = container.new HashPerson("willy");

На самом деле мое практическое правило заключается в создании любого вложенногокласс статический, если только у меня нет особых причин не делать этого.Это также более эффективно, потому что нестатические вложенные классы (называемые внутренние классы ) всегда содержат неявную ссылку на содержащий объект.

8 голосов
/ 01 ноября 2010

Вам нужно либо сделать ваш внутренний класс статическим, либо обращаться к нему через экземпляр внешнего класса. Скорее всего, вы просто хотите сделать свой внутренний класс статичным.

Нестатические члены класса (переменные, методы, внутренние классы) составляют на экземпляр класса. Поэтому при доступе к нестатическим элементам из статического контекста (например, статического метода, такого как testHashCodeOverride), вам необходимо указать экземпляр включающего класса.

...