Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / FAQ. Миф 1-ый. / 25 сообщений из 34, страница 1 из 2
24.01.2005, 17:17
    #32880742
riman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
Признаться до последнего момента я находился в заблуждении относительно передачи параметров в функцию в Jave.
Для того, кто раньше работал с С или С++ предложение "примитивы в Java передаются по значению, а объекты по ссылке" не вызывает никаких вопросов или подозрений. А на самом деле они должны их вызывать!
К первой части предложения никаких претензий нет: всё здесь аналогично С++, т.е. значение переменной копируется и действия в функции производятся уже над копией. Пример, file Example1.java:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
 public   class  Example1 {
     public   static   void  main(String arg[]){
        Example1 ex= new  Example1();
         int  orig_parameter= 1 ;
        System.out.println("Before function call\n    orig_parameter="+orig_parameter);
        ex.changeValues(orig_parameter);
        System.out.println("After function call\n    orig_parameter="+orig_parameter);
        System.exit( 0 );
    }
     public   void  changeValues( int  parameter){
        parameter= 2 ;
        System.out.println("inside changeValues function");
        System.out.println("    parameter="+parameter);
    }
}
и вывод:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Before function call
    orig_parameter= 1 
inside changeValues function
    parameter= 2 
After function call
    orig_parameter= 1 

Process finished with exit code  0 
Это то, что и ожидалось.

Теперь перейдем к объектам.
file Example2.java:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
 public   class  Example2{
     public   static   void  main(String[] args){
        Example2 ex= new  Example2();
        String orig_parameter= new  String("the original string");
        System.out.println("Before function call\n orig_parameter="+orig_parameter);
        ex.changeValues(orig_parameter);
        System.out.println("After function call\n orig_parameter="+orig_parameter);
        System.exit( 0 );
    }
     public   void  changeValues(String toChange){
        toChange="the new string";
        System.out.println("inside changeValues function");
        System.out.println(" toChange="+toChange.toString());
    }
}
Программист на С++, увидев подобный код сказал бы, что предпоследняя строчка в коде main() должна бы была вывести:
Код: plaintext
1.
2.
After function call
 orig_parameter=the  new  string
Но это не так! На самом деле вывод программы будет таким:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Before function call
 orig_parameter=the original string
inside changeValues function
 toChange=the  new  string
After function call
 orig_parameter=the original string

Process finished with exit code  0 
Как видно объект нисколько не изменился.

Чтобы прояснить ситуацию, рассмотрим след. пример.
file Example3.java:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
 public   class  Example3{
     public   static   void  main(String[] args){
        Example3 ex= new  Example3();
        MyObject obj= new  MyObject();
        System.out.println("Before function call\n orig_parameter="+obj.mystring);
        ex.changeValues(obj);
        System.out.println("After function call\n orig_parameter="+obj.mystring);
        System.exit( 0 );
    }
     public   void  changeValues(MyObject obj){
        obj.mystring="the new string";
        System.out.println("inside changeValues function");
        System.out.println(" toChange="+obj.mystring);
    }
}
 class  MyObject{
    String mystring= new  String("the original string");
}
и результат работы программы:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
Before function call
 orig_parameter=the original string
inside changeValues function
 toChange=the  new  string
After function call
 orig_parameter=the  new  string

Process finished with exit code  0 
Т.е. в этом примере объект действительно был передан по ссылке.
В чем же разница между двумя последними примерами?
Итак надо понять, что в обоих примерах внутри функции changeValue() создается ещё одна ссылка на передаваемый объект, т.е. она является копией ссылки, передаваемой в функцию.
Внутри функции changeValue() формальному параметру toChange присваивается новая ссылка
Код: plaintext
1.
toChange="the new string";
, которая уничтожается по выходе из функции. Вот почему значение строки во втором примере осталось неизменно.
В последнем примере так же создается копия ссылки на объект передаваемый функции, но "изменение" объекта, т.е. поля класса MyObject, происходит методами самого объекта. Вот почему при выходе из функции, строка сохраняет изменения, произведенные в функции.
...
Рейтинг: 0 / 0
24.01.2005, 17:39
    #32880844
Евгений Путилин
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
Да. Как обманчива природа говорил ежик слазия с кактуса.
Ошибка довольнотоки распространенная, дело в том что ты передаеш не объект по ссылке а куазательна объектю И когда переприсваиваеш значение указателя то в этом случаее на переданный исходный указатель это ни как не влияет.
Для прграмиста C++ как раз все ясно и понятно если учесть что -> заменяеться на .
И работаем все время с указателями.
...
Рейтинг: 0 / 0
24.01.2005, 19:51
    #32881127
NotGonnaGetUs
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
Евгений Путилин
Для прграмиста C++ как раз все ясно и понятно если учесть что -> заменяеться на .
И работаем все время с указателями.

Программист на С++ (в топике java vs с++) утверждал, что часть объектов передаётся по значению (String), а часть по ссылке...

Не надо говорить за всех %)
...
Рейтинг: 0 / 0
25.01.2005, 09:00
    #32881457
www.fun4me.narod.ru
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
>> что часть объектов передаётся по значению (String), а часть по ссылке...

String передаётся так же, как и все объеты. Просто в природе не существует методов, которые изменили бы внутренность String'а. Если кто хочет класс, который ведёт себя так же, как простой тип, то он должен убрать оттуда все методы, которые могут менять содержимое текущего объекта.
...
Рейтинг: 0 / 0
25.01.2005, 10:18
    #32881595
Ctrl+Alt+Delete
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
rimanПризнаться до последнего момента я находился в заблуждении относительно передачи параметров в функцию в Jave.
Для того, кто раньше работал с С или С++ предложение "примитивы в Java передаются по значению, а объекты по ссылке" не вызывает никаких вопросов или подозрений. А на самом деле они должны их вызывать!
К первой части предложения никаких претензий нет: всё здесь аналогично С++, т.е. значение переменной копируется и действия в функции производятся уже над копией. Пример, file Example1.java:


Никакого мифа здесь нет.
Все дело в том, что в Java объекты типа String являются НЕИЗМЕНЯЕМЫМИ !
Поэтому orig_parameter всегда указывает на строку "the original string"
Для работы с изменяемыми строками служит StringBuffer
...
Рейтинг: 0 / 0
25.01.2005, 10:28
    #32881619
riman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
Ctrl+Alt+DeleteНикакого мифа здесь нет.
Все дело в том, что в Java объекты типа String являются НЕИЗМЕНЯЕМЫМИ !
Поэтому orig_parameter всегда указывает на строку "the original string"
Для работы с изменяемыми строками служит StringBuffer
Причем здесь изменяемость/неизменяемость? Я что, не могу присвоить ссылку на новый объект в куче?
...
Рейтинг: 0 / 0
25.01.2005, 10:46
    #32881689
NotGonnaGetUs
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
rimanПричем здесь изменяемость/неизменяемость? Я что, не могу присвоить ссылку на новый объект в куче?
Наверное не все уловили мой сарказм :(
...
Рейтинг: 0 / 0
25.01.2005, 10:52
    #32881715
А.Грасоff™
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
NotGonnaGetUs rimanПричем здесь изменяемость/неизменяемость? Я что, не могу присвоить ссылку на новый объект в куче?
Наверное не все уловили мой сарказм :(я уловил, не расстраивайся :)
...
Рейтинг: 0 / 0
25.01.2005, 11:02
    #32881761
J--
J--
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
Чрезвычайно интересно.
еще про "Миф n-й: перегрузка операторов", пожалуйста.
Почему это для String "+" перегружен, может и у этого дела есть анатомия?
...
Рейтинг: 0 / 0
25.01.2005, 11:15
    #32881808
А.Грасоff™
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
J--Чрезвычайно интересно.
еще про "Миф n-й: перегрузка операторов", пожалуйста.
Почему это для String "+" перегружен, может и у этого дела есть анатомия?

перегрузки операторов нет. значит, нет мифа. почему для String возможен
оператор "+" - так определено спецификацией языка :)
...
Рейтинг: 0 / 0
25.01.2005, 11:23
    #32881835
riman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
засрале топег! (с) народное творчество.
...
Рейтинг: 0 / 0
25.01.2005, 11:26
    #32881851
NotGonnaGetUs
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
2riman:
не было такого.

J--Чрезвычайно интересно.
еще про "Миф n-й: перегрузка операторов", пожалуйста.
Почему это для String "+" перегружен, может и у этого дела есть анатомия?

Анатомия - что бы от System.out не тошнило :)

А вообще, мне кажется, это следствие желания сделать из String аналог "примитивного" типа.

Кроме '==' к объектам не может быть применён ни один оператор.
'+' применяется к object.toString() только в контексте конкатации строк (один из операторов явный String).
...
Рейтинг: 0 / 0
25.01.2005, 11:26
    #32881854
Ctrl+Alt+Delete
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
riman Ctrl+Alt+DeleteНикакого мифа здесь нет.
Все дело в том, что в Java объекты типа String являются НЕИЗМЕНЯЕМЫМИ !
Поэтому orig_parameter всегда указывает на строку "the original string"
Для работы с изменяемыми строками служит StringBuffer
Причем здесь изменяемость/неизменяемость? Я что, не могу присвоить ссылку на новый объект в куче?

можешь
вот пример, который работает:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
 public   class  Example2{
     public   static   void  main(String[] args){
        Example2 ex =  new  Example2();
        StringBuffer orig_parameter= new  StringBuffer("the original string");
        System.out.println("Before function call\n orig_parameter="+orig_parameter.toString());
        ex.changeValues(orig_parameter);
        System.out.println("After function call\n orig_parameter="+orig_parameter.toString());
        System.exit( 0 );
    }
     public   void  changeValues(StringBuffer toChange){
        toChange.replace( 0 , toChange.length(),"the new string");
    }
}
...
Рейтинг: 0 / 0
25.01.2005, 11:28
    #32881868
NotGonnaGetUs
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
Ctrl+Alt+Delete
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
 public   class  Example2{
     public   static   void  main(String[] args){
        Example2 ex =  new  Example2();
        StringBuffer orig_parameter= new  StringBuffer("the original string");
        System.out.println("Before function call\n orig_parameter="+orig_parameter.toString());
        ex.changeValues(orig_parameter);
        System.out.println("After function call\n orig_parameter="+orig_parameter.toString());
        System.exit( 0 );
    }
     public   void  changeValues(StringBuffer toChange){
        toChange.replace( 0 , toChange.length(),"the new string");
    }
}


Это пример чего? :)
Бесполезного вызова replace, который создаёт новый String, но который никто не использует?
...
Рейтинг: 0 / 0
25.01.2005, 11:32
    #32881884
NotGonnaGetUs
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
NotGonnaGetUs Ctrl+Alt+Delete
[/src]

Это пример чего? :)
Бесполезного вызова replace, который создаёт новый String, но который никто не использует?


Тьфу, там же StringBuffer.
Всё равно не понял к чему пример :(
...
Рейтинг: 0 / 0
25.01.2005, 11:36
    #32881901
Timm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
rimanзасрале топег! (с) народное творчество.
патпесался.
...
Рейтинг: 0 / 0
25.01.2005, 11:38
    #32881909
Ctrl+Alt+Delete
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
NotGonnaGetUs NotGonnaGetUs Ctrl+Alt+Delete
[/src]

Это пример чего? :)
Бесполезного вызова replace, который создаёт новый String, но который никто не использует?


Тьфу, там же StringBuffer.
Всё равно не понял к чему пример :(

пример что строковые объекты передаются по ссылке, и что пример со String - это особый случай
...
Рейтинг: 0 / 0
25.01.2005, 11:45
    #32881941
NotGonnaGetUs
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
Ctrl+Alt+Deleteпример что строковые объекты передаются по ссылке, и что пример со String - это особый случай
Хмм. А где говорилось, что String чем-то отличается от других объектов java ?
Напиши toChange = new StringBuffer("new string") и будет тоже самое. Об этом и пишет автор топика.
...
Рейтинг: 0 / 0
25.01.2005, 11:50
    #32881964
А.Грасоff™
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
остановитесь!!!

--
Lacrima Mosa Est
...
Рейтинг: 0 / 0
25.01.2005, 11:52
    #32881970
riman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
авторпример что строковые объекты передаются по ссылке, и что пример со String - это особый случай
Б*** я вообще то пытался объяснить простой пример, который работает на Сишнике и который работает иначе на жабе. Если не мешать "указатели и ссылки" (в доках пишут именно "ссылка"). Попробуйте написать на сишнике код где в функцию передается ссылка на объект и в ней объект изменяется (перенаправляется ссылка, удаляется, режется ;№%*(?№;(%?; и т.д. короче). Что получим после отработки функции? Редактированный объект!

ЗЫ. С Це давно не работал, может быть "указатели" и "ссылка" использую наоборот. Но вроде суть выразил.
...
Рейтинг: 0 / 0
25.01.2005, 12:54
    #32882189
Ctrl+Alt+Delete
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
riman
Б*** я вообще то пытался объяснить простой пример, который работает на Сишнике и который работает иначе на жабе.

сорри ...торможу
...
Рейтинг: 0 / 0
25.01.2005, 13:40
    #32882312
Лиман Артём
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
riman авторпример что строковые объекты передаются по ссылке, и что пример со String - это особый случай
Б*** я вообще то пытался объяснить простой пример, который работает на Сишнике и который работает иначе на жабе. Если не мешать "указатели и ссылки" (в доках пишут именно "ссылка"). Попробуйте написать на сишнике код где в функцию передается ссылка на объект и в ней объект изменяется (перенаправляется ссылка, удаляется, режется ;№%*(?№;(%?; и т.д. короче). Что получим после отработки функции? Редактированный объект!

ЗЫ. С Це давно не работал, может быть "указатели" и "ссылка" использую наоборот. Но вроде суть выразил.

на яве не программил но думаю в .NET'e аналогичная ситуёвина, объясняю.
в .нете стринг это тоже reference type (ну тобишь ссылочный), любая манипуляция со строкой ведет к созданию новой строки..
что происходитт когда ты передаеш в метод параметр? он ВСЕГДА копируется.
у тебя есть два типа параметров - просто стековые объекты и указатели.
в первом случае копируется весь объект, поэтому изменений по выходу ты не увидиш. строка - не стековый, тоесть из кучи, передается как указатель, НО, что такое указатель, то две области памяти. первая находится в стэке - это адрес ( просто int - просто число - которое трактуется как адрес в куче), так вот копируется этот самый адрес, но в твоем случае ты пытаешся чикнуть адрес - который есть копией.
ну а что с byRef параметром?
есть такая конструкция сишная int* - указатель на инт, а есть int** - указатель на указатель, так вот byRef - это указатель на указатель, в этом случае ты могеш менять даже саму ссылку..

вот еще один банальный пример:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
class Test
{
 public string S = "Origin";
}

void A(Test param)
{
 param = new Test();
 param.S = "New Val";
 Console.WriteLine("Value in void = {0}", param.S)
}

void Main()
{
  Test t = new Test();
  A(t);
  Console.WriteLine("Value after change  = {0}", t.S)
}

//результат:
//Value in void =  New Val
//Value after change  = Origin



я ясно объяснил?
...
Рейтинг: 0 / 0
25.01.2005, 13:49
    #32882338
Timm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
Лиман Артёмна яве не программил но думаю в .NET'e аналогичная ситуёвина, объясняю.
...
я ясно объяснил?
забавная "ситуевина" :)
...
Рейтинг: 0 / 0
25.01.2005, 13:52
    #32882350
Лиман Артём
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
Timm Лиман Артёмна яве не программил но думаю в .NET'e аналогичная ситуёвина, объясняю.
...
я ясно объяснил?
забавная "ситуевина" :)
на самом деле ничего смешного, при проэктировании технологии .NET многое взялось из явы (включая и синтаксис), и работа со строками от явы же, так что можно проводить аналогию
...
Рейтинг: 0 / 0
25.01.2005, 13:52
    #32882351
riman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
FAQ. Миф 1-ый.
А ты кому объяснял?
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / FAQ. Миф 1-ый. / 25 сообщений из 34, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]