Обидно , тут почти всем понятно , что длина method1 равна 12, а длина method10 равна 3. А мне вот например не понятно, и вот почему. На прошлых лекциях мы вставляли стэковый массив и в метод1 и в метод 5. И помните что было ? StackTraceElement[] stackTraceElements , будучи вставленным в конце внизу страницы заполнялся на всю катушку - с помощью метода getMethod Name мы получали в списке все вложенные методы и плюс getStackTrace() и плюс main. А вот при объявлении стэкового массива в первом методе, массив в заполнялся всего на три элемента. А поскольку искомая величина method .length есть длина вставленного в метод стека , то не ясно, почему сейчас значения прямо противоположные вчерашним.
Андрей
15 уровень
Почему в этой задаче всё наоборот?
Обсуждается
Комментарии (22)
- популярные
- новые
- старые
Для того, чтобы оставить комментарий Вы должны авторизоваться
IceBergMaster
8 февраля 2020, 17:20
Какая разница где на странице что находится, смотреть нужно на вызываемые методы.
Вот ты в мейне вызвал method10 и получил стектрейс - сколько методов было вызвано по факту?
+1
Андрей
8 февраля 2020, 19:20
Еще раз вернемся к первой задачке лекции стэки https://javarush.com/quests/lectures/questsyntax.level09.lecture01
public class ExceptionExample
{
public static void main(String[] args)
{
method1();
}
public static void method1()
{
method2();
}
public static void method2()
{
method3();
}
public static void method3()
{
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
for (StackTraceElement element : stackTraceElements)
{
System.out.println(element.getMethodName());
}
}
}
Вот какой результат мы получим:
getStackTrace
method3
method2
method1
main
Вот этот последний столбец из методов как раз и определяет размер стэка, который находится в методе 3.
Соответственно я могу сказать, что длинна метода3 равна равна 3+2=5. Если бы методов было 10, то длина мы метода10 была равна 12.
Разницы между этой задачей и задачей 903, которую мы решаем нет никакой. о там длина метода 10 равна 3.
0
IceBergMaster
8 февраля 2020, 19:22
В корне неправильное понимание стека, у метода3 длина стека может быть 3, 5, 10 хоть 100, всё зависит от цепочки вызовов.
0
Андрей
8 февраля 2020, 19:41
Так что же такое длина метода?
Это размер стэкового массива прописанного в этом методе
или это число вложении , т.е как глубоко упакован метод.
Вот вы пишете что у метода три , который вложен в два/один размер стэка может быть любым. Я этого не понимаю, мне кажется он может быть только 5. об этом говорит вот эта известная цепочка. getStackTrace
method3
method2
method1
main
0
IceBergMaster
8 февраля 2020, 19:47
"Так что же такое длина метода?" - это ты мне скажи, я с таким понятием не знаком.
"или это число вложении , т.е как глубоко упакован метод." - вот количество вложений, это и есть по сути длина/глубина стека.
Если думаешь, что может быть только 5 у метода3, так вызови третий метод в мейне, какой будет размер?
0
Андрей
8 февраля 2020, 20:23
длина метода это method().length.
вызови третий метод в мейне,
Мы говорим о вложенных методах. Сейчас третий вложенный в 2/1 поэтому его длина(расмер массива стэка ) равна 5. Если я поменяю задачу и вызову третий метод напрямую то число вложений будет на два меньше и его длина станет равной трем. Чтобы
длине стать равной 100 , необходимо третий метод упаковать в 98 вызовов.
Но почему то считается, что в задачке 904 method10 хотя и упакован в 9 методов, почему-то имеет длину 3, потому что якобы запускается напрямую из метода main/ Нет там такого. Поэтому стэк расположеннй в методе 10
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
for(StackTraceElement p: stackTraceElements )
System.out.println(p.getMethodName());
выдает нам следующую картину
getStackTrace
method10
method9
method8
method7
method6
method5
method4
method3
method2
method1
main
getStackTrace
method10
main
Разве это не есть длина метода 10 - method10.length ?
0
IceBergMaster
8 февраля 2020, 20:34
"длина метода это method().length" - ты хочешь сказать, что у любого метода так можно посмотреть длину?) Здесь ты просто смотришь длину того объекта, который возвращает метод, здесь по счастливому стечению обстоятельств метод возвращает массив стек элементов, который имеет размер(length), никакого понятия "длина метода" не существует, вот будет мой метод число возвращать число, или вообще void, размер чего ты тогда смотреть будешь?
"Мы говорим о вложенных методах" - да никто здесь никуда не вложен, есть просто метод, а вызывать его может кто угодно и где угодно, вот здесь метод3 вызывается только из метода2, а что тебе мешает вызвать метод3 из мейна? Он что тогда будет вложен в мейн?
"потому что якобы запускается напрямую из метода main/ Нет там такого." - значит посмотри ещё раз, потому что именно так и ЕСТЬ.
0
IceBergMaster
8 февраля 2020, 20:37
Ответь мне на просто вопрос, сколько методов вызывается в этой программе?
0
Андрей
8 февраля 2020, 21:07
Вызывается метод 10 (строка 5), который сразу исполняется в строке 63
Потом вызывается первый, который генерирует последовательность вызовов со второго до 10. Итого 11.
По моему представлению стэк , лежащий в method10 должен выдать 12 методов(вложенных) . А вот что делать ему с прямым вызовом из main я не представляю. Так какой у него размер 12 или 3?
+1
IceBergMaster
8 февраля 2020, 21:11
"Потом вызывается первый" - вот ГДЕ, покажи мне пальцем, вызывается первый?
Стек нигде не лежит в методах, он есть один, есть всегда, лишь изменяется в зависимости от ситуации.
0
hidden #2020490
8 февраля 2020, 21:12
" Вызывается метод 10 (строка 5), который сразу исполняется в строке 63 Потом вызывается первый, который ...."
И где потом вызывается первый?
0
Андрей
8 февраля 2020, 21:42
А то что на 8 строке как называется? Конструктор или что? Или вызывать можно только из main, а из сольюшн нельзя?
0
Андрей
8 февраля 2020, 21:49
1. ну вот я не знаю как отличить метод вызываемый от невызываемого. Почему-то main он вызывается, а в Solution такой же уже нет.
2. как это не лежит. А когда я вставляю выражение StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); в метод , значит он там лежит и отвечает за этот метод. Стоит мне его переложить в другой метод то все параметры, как то длина, число вызовов меняются.
0
hidden #2020490
8 февраля 2020, 21:54
В 8 строке метод1 только обьявляется, когда в мейн вызывается метод10, 1-9 методы не учавствуют.
0
IceBergMaster
8 февраля 2020, 21:55
Ещё раз, нигде этот стек не лежит, метод getStackTrace() возвращает ТЕКУЩЕЕ состояние стека, и очевидно же, что в каждом методе его состояние будет другим, так как на вершине ТЕКУЩЕГО стека всегда будет лежать ТЕКУЩИЙ метод. Стек вообще никак не описывает метод, он описывает состояние программы.
Если не понимаешь разницы между объявлением/описанием метода, и его вызовом, тогда у тебя очень большой пробел, который срочно нужно заполнить, прочитав материалы о методах.
0
Андрей
8 февраля 2020, 22:18
Да, методы и классы слабое мое место. Почитал , объявление это когда запускается процедура и освобождается место в памяти, а описание это установка идентификатора и связывния атрибутов с ним. Как это реально выглядит можно только догадываться. судя по твоей картинке при объявлении только одно словечко и скобки, а при описании ставится еще тип и идентификаторы.
Ну все . спасибо огромное, в башке сразу всё прояснилось. оказывается причиной непонимания было незнание где объявление , а где описание. В нашей задачке в отличие от лекционной, только два вызова методов 1 и 10 из метода main/. Всё понятно.
+2
IceBergMaster
8 февраля 2020, 22:26
Разница между объявлением и описанием то такое, главное понимать разницу с вызовом.
0
hidden #2020490
8 февраля 2020, 23:02
Может пригодится.
Джеймс Гослинг. Язык программирования Java.
... в хорошо спроектированном классе данные обычно скрываются, чтобы они могли изменяться только методами этого класса. Чтобы вызвать метод, необходимо указать имя объекта и имя метода и разделить их точкой (.). Параметры передаются методу в виде заключенного в скобки списка значений, разделяемых запятыми. Даже если метод вызывается без параметров, все равно необходимо указать пустые скобки. Объект, для которого вызывается метод (объект, получающий запрос на вызов метода) носит название объекта-получателя, или просто получателя.
В качестве результата работы метода может возвращаться только одно значение. Чтобы метод возвращал несколько значений, следует создать специальный объект, единственное назначение которого — хранение возвращаемых значений, и вернуть этот объект.
Каждый метод имеет ноль или более параметров. Метод может возвращать значение или объявляться с ключевым словом void, которое означает, что метод ничего не возвращает. Операторы метода содержатся в блоке между фигурными скобками { и }, которые следуют за именем метода и объявлением его сигнатуры. Сигнатурой называется имя метода, сопровождаемое числом и типом его параметров.
Статические методы обычно предназначаются для выполнения операций, специфичных для данного класса, и работают со статическими полями, а не с конкретными экземплярами класса.
Статический метод не может напрямую обращаться к нестатическим членам. При вызове статического метода не существует ссылки на конкретный объект, для которого вызывается данный метод. Впрочем, это ограничение можно обойти, передавая ссылку на конкретный объект в качестве параметра статического метода. Тем не менее в общем случае статические методы выполняют свои функции на уровне всего класса, а нестатические методы работают с конкретными объектами.
0
Андрей
9 февраля 2020, 08:56
За ссылку спасибо, но не очень учит отличать одно от другого. Живое общение оно полезней. Вот пример
public static void method1()
{
method2();
}
Один метод объявляется , другой вызывает. В чем отличия? Я вижу три:
1. фигурные скобки
2 точка с запятой
3 спецификаторы public static void (по-моему так они называются)
0
IceBergMaster
9 февраля 2020, 10:05
Тебе не в каких-то символах нужно отличия искать, а в том, как выполняется программа.
После компиляции, программа начинает своё выполнение(runtime) начиная с точки входа(main), и дальше инструкции выполняются строго в той последовательности, которую ты указываешь командами. Компиляция и выполнение - очень разные вещи, которые тебе тоже нужно сейчас почитать.
0
hidden #2020490
9 февраля 2020, 11:26
Делай скидку на то, что если я и знаю больше тебя, то не намного ))
Правильно, метод1 обьявляется/определяется. Внутри его вызывается метод2. Метод2 из метода1 будет вызван только после вызова метода1.
Или можно вызвать метод2 непосредственно из программы.
method2(); если метод статический
object.method2(); если не статик
(здесь оба без параметров)
Программа начинает выполняться из метода main. Если метод1 не вызывается в main ( или других методах/конструкторах/хз_где) код внутри метода выполняться не будет.
0
Андрей
10 февраля 2020, 20:26
Короче, что бы мы там не написали, выполнение начинается только с main
0