LINUX.ORG.RU
ФорумTalks

Фокусы Java


0

0

Вопрос: Модификатор поля (переменной класса) «final» — «объявляет, что значение переменной присваивается всего один раз, при ее инициализации» (К.Арнольд и Д.Гослинг «Язык программирования Java»). Приведите пример, когда волшебным образом, можно менять поле с модификатором «final» столько раз, сколько душе угодно. Подсказка — это поле вы, уважаемый Читатель, наверняка знаете и довольно часто используете в своих программах на Java.

Ответ: Пришло несколько писем, где правильно указали имя этого широко известного и повсеместно всеми применяемого и изменяемого(!) поля с модификатором «final». Но никто не указал — почему это происходит? Почему вообще возможно «переписать финал» в java. Кто и что позволяет это сделать? А как Вы считаете, лично Ваши переменные с модификатором поля «final» кто-либо может изменить? И если да, то каким именно способом?

Вопрос: Если, при создании класса, приписать методу атрибут доступа «private», то доступ к такому методу может быть осуществлен только из самого класса. Приведите пример, когда разработчик класса должен создавать методы класса с атрибутом доступа «private», но нигде(!) в своем классе, не использовать вызов этих методов. Вот как удивлялся этому волшебству Д. Флэнэген в своей книге «Java in a Nutshell»: «… Как ни странно, но эти методы не определены ни в одном из интерфейсов. Их следует объявлять как „private“, что также вызывает некоторое удивление, поскольку они вызываются извне…». Кому же нужны такие методы? Кто их вызывает извне и как?

Ответ: На это вопрос также поступило несколько писем, где правильно — когда именно разработчик класса должен создавать методы класса с атрибутом доступа «private», но нигде(!) в своем классе, не использовать вызов этих методов. Но никто не написал — почему вообще такое возможно? И можете ли Вы вызывать методы другого класса, определенные с атрибутом доступа «private»? И если да, то каким именно способом? Полный ответ на этот вопрос такой же и как на предыдущий. Все очень просто. ;-) Отгадка механизма этого «фокуса» похожа на разоблачение фокусника, достающего кролика из совершенно пустого ящика. И когда зрителю раскрывают секрет этого фокуса, то по зрительному залу проносится вздох: «Я так и знал, что у этого ящика есть двойное дно!». ;-) Затем интерес к фокусу пропадает и фокуснику приходиться придумывать новый фокус, используя тот же механизм, но в другой упаковке — он начинает, например, распиливать женщину. ;-)

Как видно автор, редиска, так отведа и не дал, так какие же ответы?

ps. взято здеся http://www.javable.com/columns/robinson/analytics/08/

★★☆

Вдоль. Надо просто мегобайтами писать код и ложить болт на все модификаторы и все тонкие места в яве.

kklausd ()
Ответ на: комментарий от iZEN

ну эту феерию я читал, но автор таки пишет «где правильно указали имя этого широко известного и повсеместно всеми применяемого и изменяемого(!) поля с модификатором „final“» так чтож то за поле?

wfrr ★★☆ ()

ну и что такого. мне через рефлекшн приходилось доставать значения private полей класса, а в тестах даже задавать свои значения в private поле класса из вне.

Tails ()
Ответ на: комментарий от wfrr

>Если, при создании класса, приписать методу атрибут доступа «private», то доступ к такому методу может быть осуществлен только из самого класса.

что неверно. я могу вызвать private метод извне

Tails ()
Ответ на: комментарий от Tails

> >Если, при создании класса, приписать методу атрибут доступа «private», то доступ к такому методу может быть осуществлен только из самого класса.

что неверно. я могу вызвать private метод извне

вопрос был «Приведите пример, когда разработчик класса должен создавать методы класса с атрибутом доступа „private“, но нигде(!) в своем классе, не использовать вызов этих методов.»

name_no ★★ ()
Ответ на: комментарий от Tails

Неа, ты дал неверный ответ и не на вопрос. Вопрсо там был такой «Приведите пример, когда разработчик класса должен создавать методы класса с атрибутом доступа „private“, но нигде(!) в своем классе, не использовать вызов этих методов.»

там ответом скорее будет

 Classes that require special handling during the serialization and deserialization process must implement special methods with these exact signatures:

 private void writeObject(java.io.ObjectOutputStream out)
     throws IOException
 private void readObject(java.io.ObjectInputStream in)
     throws IOException, ClassNotFoundException;
 private void readObjectNoData()
     throws ObjectStreamException;
wfrr ★★☆ ()

Формально, по второму вопросу, метод может дернуть вложенный класс:

public class Ololo
{
	private void Foo()
	{
		System.out.println("Foo!");
	}
	
	public static class InnerOlolo
	{
		public void TestFoo()
		{
			Ololo ololo = new Ololo();
			ololo.Foo();
		}
	}

	public static void main(String[] args)
	{
		InnerOlolo obj = new InnerOlolo();
		obj.TestFoo();
	}
}


Amp ★★★ ()
Ответ на: комментарий от Amp

> «Приведите пример, когда разработчик класса должен создавать методы класса с атрибутом доступа „private“, но нигде(!) в своем классе, не использовать вызов этих методов»

Или же, например в java.lang.Math приватный конструктор, по достаточно понятным причинам.

Amp ★★★ ()
Ответ на: комментарий от Amp

кстати да, также можно у вложенного класса делать методы и поля приватными, тогда «внешний» клас всеравно будет иметь к ним доступ, однако,

«пример, когда разработчик класса должен » а не _может_

wfrr ★★☆ ()

Re: Фокусы Java

Жаба... Но зачем?

shahid ★★★★★ ()
Ответ на: комментарий от wfrr

ну поменя final через reflection

легко

package my;

/**
* Created by IntelliJ IDEA.
* User: sergey
* Date: Feb 28, 2010
* Time: 3:15:24 AM
* To change this template use File | Settings | File Templates.
*/
public class MyClass {

private final String message;// = "Hello World";

public MyClass() {
message = "Hello world";
}

public String getMessage() {
return message;
}

private void internalMethod() {
System.out.println("call internal");
}
}

package test;

import my.MyClass;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;

/**
* Created by IntelliJ IDEA.
* User: sergey
* Date: Feb 28, 2010
* Time: 3:16:03 AM
* To change this template use File | Settings | File Templates.
*/
public class TestClass {

public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
MyClass mc = new MyClass();
System.out.println(mc.getMessage());
Field field = mc.getClass().getDeclaredField("message");
field.setAccessible(true);
field.set(mc, "Surprise");
System.out.println(mc.getMessage());
Method intMethod = mc.getClass().getDeclaredMethod("internalMethod");
intMethod.setAccessible(true);
intMethod.invoke(mc);
}
}

вывод:

Hello world Surprise call internal

sun java 1.6.0_17

Tails ()

Так понимаю, проблема в нечтении документации, а авторов...

madcore ★★★★★ ()
Ответ на: комментарий от Tails

куй с тобой золотая рыбка, а как насчет подсказки «Подсказка — это поле вы, уважаемый Читатель, наверняка знаете и довольно часто используете в своих программах на Java. »

wfrr ★★☆ ()
Ответ на: комментарий от name_no

подвинтесь, я тоже хочу на него накакать.

wfrr ★★☆ ()
Ответ на: комментарий от name_no

самое интересное что если раскоментарить

private final String message;// = «Hello World»;

и убрать инициализацию в конструкторе
public MyClass() {
message = «Hello world»;
}

то вывод будет
Hello world
Hello world
call internal

хотя final поле переопределится, но метод getMessage() в этом случае будет оптимизирован на этапе компиляции, поэтому с такой хренью надо быть очень аккуратным

Tails ()
Ответ на: комментарий от name_no

>И эти люди обсирают C++...

а что? у нас это называется на свой страх и риск, а в C++ запись вида (*int((*int)(int[])))(int, int**) называется нормальным положением вещей

Tails ()
Ответ на: комментарий от Tails

у меня static final емнип не менялось (инициализировалось при объявлении), так как я так не извращаюсь то полагал что это справедливо для любых final

wfrr ★★☆ ()
Ответ на: комментарий от iZEN

ять.

«Приведите пример, когда волшебным образом, можно менять поле с модификатором „final“ столько раз, сколько душе угодно. Подсказка — это поле вы, уважаемый Читатель, наверняка знаете и довольно часто используете в своих программах на Java.»

до просветления, а лучше наверное спать.

wfrr ★★☆ ()
Ответ на: комментарий от iZEN

ложись уже спать, ты и днем весьма слобоадекватные мыли выдаешь

wfrr ★★☆ ()
Ответ на: комментарий от iZEN

Ты просто получишь два разных поля, да ещё в двух разных кдассах. Изменение - это когда неято было чем-то одним и стало чем-то другим. Чем были твои serialVersionUID до создания классов?

bbk123 ★★★★★ ()
Ответ на: комментарий от wfrr

>«Приведите пример, когда волшебным образом, можно менять поле с модификатором „final“ столько раз, сколько душе угодно. Подсказка — это поле вы, уважаемый Читатель, наверняка знаете и довольно часто используете в своих программах на Java.»

до просветления, а лучше наверное спать.


ну просвети уже нас, каков же ответ?

Tails ()
Ответ на: комментарий от Tails

Он сам не знает. Все известные способы уже названы.

iZEN ★★★★★ ()
Ответ на: комментарий от Tails

>у нас это называется на свой страх и риск

Это законная фича безо страха и риска. В секюрити-контексте апплета, конечно, подобный функционал закрыт.

Absurd ★★★ ()
Ответ на: комментарий от Tails

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

wfrr ★★☆ ()

стал не Ъ, и сходил по ссылке. пример редкостного бреда.


Вопрос: [«Зеленая» Java. Эта загадка от Романа Поротникова не нашла решения ни у одного из приславших мне письма с ответами. Неужели эта зелень НИКОМУ не по зубам? ;-) ]
В JBuilder (да и не только в нем) есть синтаксический анализатор кода, который показывает зеленым цветом код комментария. Напишите программу, которая вся(!) была бы окрашена в зеленый цвет: Green.java. И эта «зеленая » программа должна выводить на консоль сообщение «World is green!» — вот «зеленые» то обрадуются.

Ответ:: Конечно, вопрос довольно эффектный и многих может ввести в шок. Как так? — грузим исходник в редактор, видим одну зелень, то есть ВСЯ программа визуально(!) состоит из ОДНИХ комментариев, запускаем программу и, на тебе, — программа работает и выводит на консоль сообщение «World is green!» Чудо да и только! А секрет прост, ведь текст в Java можно набирать не только на английском, китайском, тайваньском и русском, но и на всех этих (и многих других) языках разом, используя … Эка, я Вам уже сколько подсказал. Но задача то красивая — вся такая зеленая. Нет, пока секрет полностью не открою. Присылайте решения. ;-)

Tails ()
Ответ на: комментарий от Tails

подозреваю что зелёные зоны делаются так. правда жбилдера у меня нет и проверить как там работает анализатор кода я не могу.

package test;

/**
 * Created by IntelliJ IDEA.
 * User: sergey
 * Date: Feb 28, 2010
 * Time: 1:25:01 PM
 * To change this template use File | Settings | File Templates.
 */
public class Green {

    private static String s = "Start of green zone\u0022;

    private static void doSomething() {
        System.out.println(\u0022something\u0022);
    }

    private static String s2 = \u0022End of green zone";

    public static void main(String[] args) {
        System.out.println(s);
        doSomething();
        System.out.println(s2);
    }
}

Tails ()
Ответ на: комментарий от Tails

кстати бага ЛОРа, код не раскрасился, хотя если глянуть в сорс страницы то должен был.

<div class=code><pre class=«language-java»><code>

Tails ()
Ответ на: комментарий от Tails

Eclipse и IDEA не красят код в редакторах. Причём IDEA подчёркивает код в месте строковых литералов (ей не нравится Unicode-литерал в одной строке и не может резолвить символы в другой), однако компилирует и выполняет! Eclipse молчком всё выполняет.

iZEN ★★★★★ ()
Ответ на: комментарий от iZEN

вот почти полностью зелёная. если предположить что жбилдер немного тупее эклипса то возможно там будет полностью зелёная

/* 
*\u002F

package test; 
 
public class Green { 
 
    private static String s = "Start of green zone";
    
    private static void doSomething() {
    	System.out.println(\u0022something\u0022);
    }
    
    private static String s2 = \u0022End of green zone"; 
 
    public static void main(String[] args) { 
        System.out.println(s); 
        doSomething(); 
        System.out.println(s2); 
    } 
} 

 \u002F*
 */

пруф

http://img690.imageshack.us/img690/626/code2.png

Tails ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.