powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Убейте
25 сообщений из 55, страница 2 из 3
Убейте
    #34089019
ddocker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
АСУ ТПшник
Код: plaintext
1.
2.
3.
4.
 package  package1;
 public   class  Class1 {
     protected   void  v(){System.out.println ("Вызван метод родителя");}
}

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
 package  package2;
 public   class  Class2  extends  package1.Class1 {
     public   static   void  main(String[] args){
        package1.Class1 c =  new  Class2();
        c.v();     
    }
}

Компилируем оба класса.
...
Комментарии?

Странно... И это у тебя компилится?
Ведь, не должно же по тем же причинам, которые с самого начала обсуждались: ибо v() has protected access in package1.Class1. Или ты напрямую из коммандной строки? IDEA по крайней мере этот compile-error показывает!


Кстати, на rsdn вот прям недавно то же самое обсуждалось
...
Рейтинг: 0 / 0
Убейте
    #34089022
АСУ ТПшник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Из коммадной строки. Это оказывается очень старый баг, который заключается в том, что в runtime не проверяются уровни доступа (считается что все проверено на этапе компилляции). В 1.6 исправили
...
Рейтинг: 0 / 0
Убейте
    #34089046
ddocker
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет, я не про это.
Вот эти 2 файла изначально(Class1.java и Class2.java) как ты откомпилил? У меня и из командной строки тот же самый error пишет.
Файлы:
p1/c1.java
p2/c2.java

Компилю:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
F:\path>cmd
Microsoft Windows XP [Версия 5.1.2600]
(С) Корпорация Майкрософт, 1985-2001.

F:\path>javac p1/c1.java

F:\path>javac p2/c2.java
p2/c2.java:5: v() has protected access in p1.c1
        c.v();
         ^
1 error


Содержимое:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
// p1.c1.java
 package  p1;
 public   class  c1 {
     protected   void  v(){System.out.println ("parent");}
}

// p2.c2.java
 package  p2;
 public   class  c2  extends  p1.c1 {
     public   static   void  main(String[] args){
        p1.c1 c =  new  c2();
        c.v();     
    }
}

Может ты сначала у Class1.java public там делал?
...
Рейтинг: 0 / 0
Убейте
    #34089087
АСУ ТПшник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да, сначала делается public.
Компилится все.
Открываем исходник класса Class1.
Меняем доступ на private или protected
Компилируем ТОЛЬКО Class1
...
Рейтинг: 0 / 0
Убейте
    #34089103
он же
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
АСУ ТПшникИз коммадной строки. Это оказывается очень старый баг, который заключается в том, что в runtime не проверяются уровни доступа (считается что все проверено на этапе компилляции). В 1.6 исправили
Я лично не считаю это багом. И не понимаю, откуда вы взяли, что такое поведение - баг.
В 1.6, кстати, - ситуация ровно такая же (только что проверил). Логичная.

Все файлики в аттаче.

Код: 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.
25.
26.
27.
28.
29.
30.
31.
C:\Program Files\Java\jdk1. 6 . 0 \bin>batch

C:\Program Files\Java\jdk1. 6 . 0 \bin>del p1\*. class 

C:\Program Files\Java\jdk1. 6 . 0 \bin>del p2\*. class 

C:\Program Files\Java\jdk1. 6 . 0 \bin>copy /y p1\c_public.java p1\c1.java
Скопировано файлов:          1 .

C:\Program Files\Java\jdk1. 6 . 0 \bin>javac p1/c1.java

C:\Program Files\Java\jdk1. 6 . 0 \bin>javac p2/c2.java

C:\Program Files\Java\jdk1. 6 . 0 \bin>java p2/c2
parent

C:\Program Files\Java\jdk1. 6 . 0 \bin>copy /y p1\c_protected.java p1\c1.java
Скопировано файлов:          1 .

C:\Program Files\Java\jdk1. 6 . 0 \bin>javac p1/c1.java

C:\Program Files\Java\jdk1. 6 . 0 \bin>java p2/c2
parent

C:\Program Files\Java\jdk1. 6 . 0 \bin>javac p2/c2.java
p2\c2.java: 5 : v() has  protected  access in p1.c1
        c.v();
         ^
 1  error

C:\Program Files\Java\jdk1. 6 . 0 \bin>
...
Рейтинг: 0 / 0
Убейте
    #34089107
он же
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
еще раз :)
...
Рейтинг: 0 / 0
Убейте
    #34089181
АСУ ТПшник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
то ли вы не правлильно поняли, то ли я плохо объяснил :)
Багом здесь считается то, что в runtime не проверяется уровень доступа к полю класса. Это действительно баг, который исправили в 1.6.

Еще раз внимательно по шагам:
1. Создаем два класса.
Код: plaintext
1.
2.
3.
4.
 package  package1;
 public   class  Class1 {
     public   void  v(){System.out.println ("Вызван метод родителя");}
}
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
 package  package2;
 public   class  Class2  extends  package1.Class1 {
     public   static   void  main(String[] args){
        package1.Class1 c =  new  Class2();
        c.v();     
    }
}

2. Компиллируем эти два класса:

javac package1/Class1.java package2/Class2.java

3. После успешной компилляции заменяем в первом классе уровень доступа.
Код: plaintext
1.
2.
3.
4.
 package  package1;
 public   class  Class1 {
     private   void  v(){System.out.println ("Вызван метод родителя");}
}

4. Компиллируем только первый класс
javac package1/Class1.java

5. Запускаем получившуюся конструкцию

java package2.Class2

6. Смотрим результат. А он заключается в том, чтобы вместо того чтобы ругаться, что производися доступ к private переменной, код спокойно выполняется.

Вот здесь про это рассказано, что это очень старый и очень известный баг, что он сохранен для совместимости. И всплывает он только тогда, когда класс (файл *.class) находится на жестком диске конкретной машины, а не скачивается из интернета во время выполнения како-либо программы. Поэтому он не представляет опасности.
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4298813
...
Рейтинг: 0 / 0
Убейте
    #34089194
он же
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
АСУ ТПшникто ли вы не правлильно поняли, то ли я плохо объяснил :)
Багом здесь считается то, что в runtime не проверяется уровень доступа к полю класса. Это действительно баг, который исправили в 1.6.

Почему вы не запустили мой пример? Это так сложно?
В нем четко показано, что в 1.6 ситуация ровно такая же как и во всех остальных java-машинах. О чем вы пытаетесь спорить?

Я считаю, что это не баг. Потому что это задача не runtime-машины - проверять доступность классов.
Это задача компилятора.
А то, что вы не компилите проект (все зависимые пакеты и классы, как того требуется), а только лишь выборочно - это исключительно ваши проблемы, а не java.

This is a well-known problem. It is allowed for backward compatibility. We are going to tight up verify check during the Tiger time frame.

Причем никто не утверждает, что это баг. Есть лишь слова
I don't know if it is a bug, but it make me confused.


State тоже внушает оптимизи
Closed, will not be fixed

Так что расслабьтесь, попейте чайку :)
Поведение предсказумое, стандартное. Всё хорошо.
...
Рейтинг: 0 / 0
Убейте
    #34089358
АСУ ТПшник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. расслаблен
2. не запускал потому как дома нет 1.6.
3. если не вникли что написано, жаль, наверное кто-то из нас не умеет понимать/объяснять, ибо ваши комментарии по поводу вопроса и ответа на www.java.sun.com сугубо субъективны.
4. в 1.6. должно выскочить что то типа
авторException in thread "main" java.lang.IllegalAccessError
5. ушел рубать всех в старкрафт :)
...
Рейтинг: 0 / 0
Убейте
    #34089368
он же
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
АСУ ТПшник1. расслаблен
2. не запускал потому как дома нет 1.6.
3. если не вникли что написано, жаль, наверное кто-то из нас не умеет понимать/объяснять, ибо ваши комментарии по поводу вопроса и ответа на www.java.sun.com сугубо субъективны.
4. в 1.6. должно выскочить что то типа
авторException in thread "main" java.lang.IllegalAccessError
5. ушел рубать всех в старкрафт :)
1) Это хорошо.
2) Жаль. У меня есть. Я запускал.
3) Вник. Причем полностью. Мой пример лишь доказывает то, что я вник. А комментарии - естественно, субъективны. Вы даже не потрудились скачать исходники и сопоставить с приведенным мной результатом выполнения батника. На основе этого вы делаете далекоидущие выводы о моей тупости. Это не делает вам чести, прямо скажем.
4) Не выскакивает. Да и не должно.
5) Удачи.
...
Рейтинг: 0 / 0
Убейте
    #34089709
АСУ ТПшник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
я не делаю выводов о вашей тупости/умности. Приатачьте ваши примеры, завтра постараюсь их проанализировать(сейчас их нет), если не накроет очередная волна по работе. Это вы делаете далеко идущие выводы из непонятно чего.
...
Рейтинг: 0 / 0
Убейте
    #34089711
АСУ ТПшник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
упс, появились... что то с движком, я их то вижу то не вижу. Серьезно. Вчера ответ на некоторые посты форумчан в форум значился как более ранний по времни и поэтому выше того, на что был ответ :/
...
Рейтинг: 0 / 0
Убейте
    #34089714
он же
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Аттач, кстати, пропадает, если предварительный просмотр делать :(
...
Рейтинг: 0 / 0
Убейте
    #34092428
АСУ ТПшник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сегодня было копание в коде и астральная медитация. Похоже вы Он же были правы, и на 1.6 все хорошо так себе работает. Если подтвердятся мои подозрения, то изложу суть проблемы/решения. Но времени сейчас нет, надеюсь что на этой неделе.....
мыло оставьте.
...
Рейтинг: 0 / 0
Убейте
    #34092475
он же
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В профиле поставил и мыло, и аську :)
...
Рейтинг: 0 / 0
Убейте
    #34106712
fearow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ноль2Хоть убейте, но обьясните плиз, что здесь неправильно
Код: plaintext
1.
2.
3.
4.
 package  package1;
 public   class  Class1 {
	 protected   void  v(){}
}	

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
 package  package2;
 public   class  Class2  extends  package1.Class1 {
	 public   void  v(){}
	
	 public   static   void  main(String[] args){
		package1.Class1 c =  new  Class2();
		c.v(); 	//Class2.java:8: 
			//v() has protected access in package1.Class1
	
		Class2 c =  new  Class2();
		c.v(); 	//OK
	}
}	

Public то он public, да только в пределах пакета package1. А когда OK, вы обращаетесь к v() из класса-потомка (соответственно, и права, как для protected). Уважаемые гуру, я прав?
...
Рейтинг: 0 / 0
Убейте
    #34106713
fearow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ноль2Я до сих пор думал, что если имеет место overriding, то какой будет вызван метод определяется не типом package1.Class1 переменной с, а классом обьекта package2.Class2, на который она, переменная с, указывает???
Если имеет место overriding, то будет вызван метот, находящийся ниже всех в стеке. И так до вершины.
...
Рейтинг: 0 / 0
Убейте
    #34114084
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
АСУ ТПшник Объект класса 2 объявляется как объект класса 1. Их этого следует, что через эту ссылку (ее тип класс 1) доступны поля и методы, а так же область их доступности, только те, которые относятся к классу1 (к родительскому).
Меня лично заинтересовало другое - получается, что в этом самом объекте существет один и тот же метод, который в разных случаях имеет разную степень доступа к нему.

Че-то не вяжеться это с концепцией познего связывания... Получает в данном примере, решение какую функцию вызывать принимается на основе типа ОБЪЕКТА.

Код: plaintext
1.
2.
3.
4.
5.
 package  testPack;
 public   class  A {
	 protected   void  v(){};
} 
 package  TestPack2;
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
 import  testPack.A;
 public   class  B  extends  A{
	 protected   void  v(){};
	 public  B() {
		 super ();
		// TODO Auto-generated constructor stub
		A a =  new  B();
		a.v();
	
	}

}
А тогда он должен вызвать B.v()... Я знаю, что не прав, но не пойму почему...
...
Рейтинг: 0 / 0
Убейте
    #34114433
АСУ ТПшник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
to bemtaill

Вот что я имел ввиду. Запустите следующий код
Точка входа
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
 import  asutp.samples.ChildClass;
 import  asutp.samples.ParentClass;

 public   class  Main {
	 public   static   void  main(String[] args) {
		ParentClass parent =  new  ParentClass();
		ChildClass child1 =  new  ChildClass();
		ParentClass child2 =  new  ChildClass();
		System.out.println("parent1.a = " + parent.a);
		System.out.println("child1.a = " + child1.a);
		System.out.println("child1.b = " + child1.b);
		System.out.println("child2.a = " + child2.a);
		System.out.println("child2.b = " + child2.b);
	}
}

Вызываемые классы.
Код: plaintext
1.
2.
3.
4.
 package  asutp.samples;
 public   class  ParentClass {
 public   int  a;
}
Код: plaintext
1.
2.
3.
4.
 package  asutp.samples;
 public   class  ChildClass  extends  ParentClass {
 public   boolean  b;
}
...
Рейтинг: 0 / 0
Убейте
    #34114446
АСУ ТПшник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Но это уход от темы, собственно в приложенных файлах два кода, один запускается и выполняется на 1.6, второй нет.
Найдите пять отличий, времени разобраться почему так к сожалению не было.
Вернее я приложу не работающий код, а приложенный выше товарищем Oн Же работает нормально.
...
Рейтинг: 0 / 0
Убейте
    #34115013
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
АСУ ТПшник to bemtaill

Вот что я имел ввиду. Запустите следующий код
Точка входа
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
 import  asutp.samples.ChildClass;
 import  asutp.samples.ParentClass;

 public   class  Main {
	 public   static   void  main(String[] args) {
		ParentClass parent =  new  ParentClass();
		ChildClass child1 =  new  ChildClass();
		ParentClass child2 =  new  ChildClass();
		System.out.println("parent1.a = " + parent.a);
		System.out.println("child1.a = " + child1.a);
		System.out.println("child1.b = " + child1.b);
		System.out.println("child2.a = " + child2.a);
		System.out.println("child2.b = " + child2.b);
	}
}

Вызываемые классы.
Код: plaintext
1.
2.
3.
4.
 package  asutp.samples;
 public   class  ParentClass {
 public   int  a;
}
Код: plaintext
1.
2.
3.
4.
 package  asutp.samples;
 public   class  ChildClass  extends  ParentClass {
 public   boolean  b;
}


Я понял, что вы имели ввиду, когда разбирался весь этот геморой с поэтапной компиляцией классов и отсутствием проверки уровня доступа, при такой линковке. У меня вопрос почему в моем примере при попытке вызывать a.v();
идет обращение к A.v(), а в соответствии с тем, что все методы "виртуальные" (если мыслить в терминах C++) должен вызываться B.v()?
...
Рейтинг: 0 / 0
Убейте
    #34115088
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
bemtaill
....а в соответствии с тем, что все методы "виртуальные" (если мыслить в терминах C++) должен ...

кроме final...
...
Рейтинг: 0 / 0
Убейте
    #34115105
АСУ ТПшник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Знаете нет времени к сожалению.
Попробуйте объявить как B b
а потом привести к типу A
т.е. (A)b;
думаю тогда заработает нужный метод, это требуется для полиморфизма.
...
Рейтинг: 0 / 0
Убейте
    #34115791
bemtaill
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
АСУ ТПшникЗнаете нет времени к сожалению.
Попробуйте объявить как B b
а потом привести к типу A
т.е. (A)b;
думаю тогда заработает нужный метод, это требуется для полиморфизма.
Да все таки хочу найти ответ на свой вопрос. Помогите плз. Реально не знаю как объяснить. У Эккеля:
авторРешение называется позднее связывание, что означает, что связывание происходит во время работы программы и основывается на типе объекта. Позднее связывание так же иногда называют динамическим связыванием или связыванием во время выполнения. Когда язык поддерживает позднее связывание, то у него должен быть механизм определения типа объекта в время работы программы и вызова соответствующего метода. Все так и есть, компилятор все еще не знает какого типа этот объект, но механизм вызова методов находит его и вызывает соответствующее тело метода. Механизм позднего связывания меняется от языка к языку, но Вы можете представить себе, что в объект должна быть встроена некоторая информация о типе объекта.
В Java все методы за исключением final используют позднее связывание. И это означает, что Вам нет необходимости принимать решения, о необходимости применения позднего связывания в том или ином месте программы, поскольку это происходит автоматически.

ХЭЛП!
...
Рейтинг: 0 / 0
Убейте
    #34116595
Leonidv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
http://java.sun.com/docs/books/jls/third_edition/html/names.html#36191
...
Рейтинг: 0 / 0
25 сообщений из 55, страница 2 из 3
Форумы / Java [игнор отключен] [закрыт для гостей] / Убейте
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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