Вызов метода экземпляра в Java - PullRequest
1 голос
/ 28 августа 2009

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

Ответы [ 6 ]

3 голосов
/ 28 августа 2009

Байтовый код (или собственный код, если он JIT) для метода хранится в одном месте. Когда метод вызывается, указатель (под капотом, иначе ссылка на более высокий уровень) на объект экземпляра передается в качестве первого аргумента, чтобы код метода мог работать с этим конкретным экземпляром - иметь доступ к его полям и т. Д. Чтобы сэкономить место без дополнительных затрат производительности, механизм вызова в Java немного сложнее, чем C ++, , особенно для методов интерфейса.

2 голосов
/ 28 августа 2009

За кулисами ссылка на объект передается методу как часть вызова. Может быть полезно взглянуть на классы отражения Java, в частности Method.invoke () .

2 голосов
/ 28 августа 2009

Методы и поля совершенно разные. Методы применяются ко всем экземплярам объекта, но поля относятся к экземпляру.

Один способ думать об этом:
притвориться, что метод является «глобальным» для всех экземпляров, но ему «передается» экземпляр объекта через ссылку «this».

Методы могут изменять состояние конкретного экземпляра, но сами они не сохраняют состояния.

1 голос
/ 28 августа 2009

подразумеваемая ссылка «this» передается каждому методу, который, конечно, вы можете явно указать

1 голос
/ 28 августа 2009

Из предыдущего моего ответа:

Я уверен, что фактическая реализация сильно отличается, но позвольте мне объяснить мое представление о методе диспетчеризации, который модели точно наблюдали поведение.

Представьте, что у каждого класса есть хеш-таблица, которая отображает сигнатуры метода (имена и типы параметров) на фактический кусок кода для реализации метода. Когда виртуальная машина пытается вызвать метод в экземпляре, она получает класс объекта и ищет запрошенную подпись в таблице класса. Если тело метода найдено, оно вызывается, предоставляя исходный объект в качестве ссылки с именем this.

В противном случае родительский класс класса получается, и поиск там повторяется. Это продолжается до тех пор, пока метод не будет найден или не останется родительских классов, что приведет к NoSuchMethodError.

Если суперкласс и подкласс имеют записи в своих таблицах для одной и той же сигнатуры метода, сначала встречается версия подкласса, и версия суперкласса никогда не используется - это «переопределение».

0 голосов
/ 28 августа 2009

Я предполагаю, что вы имеете в виду на упрощенном уровне, как в том, как вы на самом деле делаете вызов. Я также предполагаю, что вы ссылаетесь на метод, который имеет модификатор static в своей подписи, то есть:

public static int getNum() 
{
  // code in here 
  return num;
}

Если это то, что вы имеете в виду, и это было частью класса с именем 'SomeClass', тогда к нему можно обратиться через вызов метода SomeClass.getNum(). т.е. вы помещаете фактическое имя класса перед методом.

Если это не то, что вы имеете в виду, игнорируйте мой ответ :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...