java-зодачго

stm6695895

сори еси боян, никак не могу разобраться... как обратиться из конструктора класса b к методу fin класса с?

package a;

import java.applet.Applet;
import java.awt.Graphics;

public class Temp extends Applet
{
public void paint(Graphics g)
{
b b = new b(g);
}
}


class c
{
static void fin(Graphics g)
{
g.drawString("ТРЕТИЙНАХ", 20,70);
}
}

class b
{
static class c
{
static void fn(Graphics g)
{
g.drawString("ВТОРОЙНАХ", 20,60);
}
}

static class a
{
static class c
{
static void fn(Graphics g)
{
g.drawString("ПЕРВЫЙНАХ", 20,50);
}
}
}

public b(Graphics g)
{
//TODO WHAT?
}
}

yolki

я не спец в джаве, но по-моему вся прогрессивная общественность давно забила на AWT и пользуется по крайней мере Swing-ом.

stm6695895

задача не про это

yolki

сначала создать экземпляр класса, нет?
или ты про то, как создать экземлпяр класса, имя которого перекрыто локальным классом?

mkrec

a.c.fin
?

yolki

у a.c нет метода fin, у него есть fn.
видимо у него проблемы с инстанциализацией класса ::c
тут я не спец.

SPARTAK3959

Метод статический, поэтому экземпляр класса не нужен. По топику - не вижу способа кроме рефлекшена. Это нужно для java-декомпилятора?

stm6695895

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

stm6695895

не выйдет

stm6695895

что за рефлекшн? это нужно просто для спортивного интереса. в си++ такое решабельно в аналогичной ситуации

yolki

как в С решить я не знаю.
в С++ я написал как - ::c

stm6695895

да, это таг. есть ли аналог в яве, хотелось бы знать...

mkrec

а, блин :(
да, в си++ в этом плане гораздо проще

krishtaf

А такое: c.fin - ошибку выдает что ли ?

stm6695895

угу. конечно выдает. в b определен свой класс c и в нем нету метода fin

pitrik2

может поэтому в java принято называть классы с большой буквы а пакеты с маленькой?

stm6695895

мбмб
просто принято-то то принято, но на такой код компиль тож не ругаецо ведь

katrin2201

Google: java fully qualified names
Вкратце - a.c.fin;

stm6695895

а можно подробнее? потому что вкратце не работает)

mkrec

такое ощущение, что некоторые (и я в том числе :( ) пишут ответ, не удосужившись дочитать листинг до конца.

njvfc1

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

package a;
/**
* Created by IntelliJ IDEA.
* User: alexsa
* Date: 22.11.2007
* Time: 21:45:13
* To change this template use File | Settings | File Templates.
*/
import java.applet.Applet;
import java.awt.Graphics;
import static a.c.fin;
public class Temp extends Applet
{
public void paint(Graphics g)
{
b b = new b(g);
}
}

class c
{
static void fin(Graphics g)
{
g.drawString("ТРЕТИЙНАХ", 20,70);
}
}
class b
{
static class c
{
static void fn(Graphics g)
{
g.drawString("ВТОРОЙНАХ", 20,60);
}
}
static class a
{
static class c
{
static void fn(Graphics g)
{
g.drawString("ПЕРВЫЙНАХ", 20,50);
}
}
}
public b(Graphics g)
{
fin(g);
}
}

stm6695895

а еси fin не статическая?

pitrik2

да причем тут фин?
ты вообще экземпляр класса c создай

Dasar

в C# это делается через слово "global::" в Java ничего такого не добавляли?

global::c.fin;

также в C# это можно сделать через alias-ы:

using c2=c;

njvfc1



да причем тут фин?
ты вообще экземпляр класса c создай
Как только так сразу.

Есть мнение что если нет статик, то никак. Это Спарта, то есть жава -)

pitrik2

в Java ничего такого не добавляли?
не слышал
но подозреваю что вряд ли добавят
оно не надо никому
ну НЕ ПРИНЯТО называть классы с маленькой буквы
вот почему этого вовсе не запрещают, хз
боятся старый код потерять? да нах он нужен?

stm6695895

да я могу их все тут с большой назвать, подумаешь)
мне просто было интересно, в принципе, возможен ли в яве выход в глобальное пространство имен. получается, что по ходу нет.

danilov

Это ты писал?
Странная архитектура. Даже если package-private классы нужны, почему бы их не выделить в отдельный файл?
А BotWi прав - правильное именование позволит избежать коллизий имён пакетов и классов.

ifani

дык, фишка-то в том, что специально так написано, чтоб были коллизии - причём тут архитектура? ;)
а вообще тут уже писали, через рефлекшн можно добраться, так как в этом случае не будет локального пространства имён - только глобальное

stm6695895

чо за рефлекшн-то?

danilov

Блин, рефлекшн - это как лечение простуды хирургическим путём. Не выход, да и медленный шопепец.

mkrec

getDeclaredClasses
мне кажется, лучше просто поменять названия классов или пакета

stm6695895

слух, ты правда думаешь, что кому-то в жизни пригодится пример выводящий на экран строчку "ТРЕТИЙНАХ"? :)
поменять имена - эт запросто конечно)

danilov

Тогда это вопрос из разряда: Можно ли прожарить мобильник во фритюрнице.
Ответ был даден... Кривой, но учитывая, что проблема решается сильно проще, а при определённой культуре
программирования вообще не можнт возникнуть, не очень понятно, что ещё можно обсуждать.
Reflection API проставляет тебе доступ к структуре твоего проекта. Полезная штука. Но толком не знаю, где её стоит применять. Из известных мне примеров - только при (де)сериализации. Поищи в инете, довольно гибкая вещь, но этетически грязновата...

stm6695895

Тогда это вопрос из разряда: Можно ли прожарить мобильник во фритюрнице.
ситуация в том, что на си++ - можно.
причем таким способом, в котором не найти никаких изъянов, никакой путаницы итд. печально, что в яве, противопоставляемой си++ и даже более того - представляемой языком, лишенным недостатков и противоречий си++ - в яве такого простого способа нет.

stm6695895

по reflection покопаю, пасип. впрочем, здесь его уже успели раскритиковать)

mkrec

в c++ совсем другая концепция, так сказать, модулей. С точки зрения c++, корень есть, а с точки зрения java - нет
что касается рефлекшна: а что, если с getPackage покрутиться?

stm6695895

 
в c++ совсем другая концепция, так сказать, модулей. С точки зрения c++, корень есть, а с точки зрения java - нет

возвращаясь к примеру в первом посте, логически рассуждая можно было бы предположить, что к методам внешнего класса c можно было бы обратиться:
a.c.fin; где первое a - имя пакета
а к внутреннему классу c: a.b.a.c.fn; или a.b.c.fn;
(в классе b их две штуки)
тут никаких противоречий не видится, несмотря ни на какое различие в концепциях с си++, и почему это не работает - мне лично непонятно

danilov

ситуация в том, что на си++ - можно. причем таким способом, в котором не найти никаких изъянов, никакой путаницы итд. печально, что в яве, противопоставляемой си++ и даже более того - представляемой языком, лишенным недостатков и противоречий си++ - в яве такого простого способа нет.
Такой уж язык. Он вроде не позиционируется как бескомпромисная замена плюсам. Что-то в одном языке есть, что-то в другом. Опять же путаницы тут никакой нет.... произошло перекрытие имён и всё. Тут никакой способ не нужен...
Когда в плюсах обращаешься к полю класса по адресу экземпляра и смещению, огребаешь по полной при наследовании... Что ж, не надо обращаться таким образом к полю класса. Есть шутливый FAQ про яйца в микроволновке. Это я к тому что в любом случае можно создать сомнительные ситуации. Вопрос, зачем?
И идея и эклипс тебе скажут, что такие названия (имена классов) противоречат code convention... Зачем идти наперекор? Опять же, например, венская конвенция. Есть замечательная статья (к сожалению, не помню ссылку, могу поискать) в защиту её. Типа, грамотное её использование позволяет существенно облегчить жизнь. Смысл в том, чтобы префиксы формировать не из типов данных и из их состояний (например, safe/unsafe). Здесь точно так же.
Следуй ряду правил, которые ставит не компилятор, а здравый смысл и опыт многих разработчиков, и буит тебе щястье

pitrik2

Но толком не знаю, где её стоит применять.
есть в джаве куча вещей которые на ней основаны
без нее их бы не было
примеры: hibernate, beanutils (а значит и struts spring, всякие удаленные вызовы типа rmi,corba ...
а зачем при (де)серилизации нужен рефлекшн?

danilov

Дефолтная сериализация - это просто иерархический обход по ссылкам, минуя transient.
Осуществряется он через reflection. Плюс неявный интерфейс readObject/writeObject, проверка
реализации которого и вызов самих методов осуществляется так же через неё

SPARTAK3959

На самом деле практически эта задача может возникнуть при декомпиляции программы пропущенной через обфускатор (который работает на уровне class-файлов где этой проблемы нет) - там имена из 1-2 букв и описанная ситуация возникнуть может. Главное, что бы об этой фиче не узнали авторы обфускаторов.

pitrik2

там имена из 1-2 букв и описанная ситуация возникнуть может
говно те обфускаторы которые названия классов с маленькой буквы делают

psm-home

почему?

bleyman

Мне чота кажется, что они о ней давно знают. По крайней мере дотнетные — точно, про дотфускатор аж специально написано, что у него унутре load™ или что-то такое, который называет одинаковыми именами ващеее всё что можно, в результате простые декомпайлеры тупо сходят с ума.

Svyatogor

Знают прекрасно. И одинаковыми именами тоже умеют все называть. Даже локальные поля, отличающиеся по типу, могут называть одним и тем же именем. Возможно, даже делают методы, отличающиеся только возвращаемыми типами. У proguard, например, переименовывания используются для J2ME-приложений (телефоны) для уменьшения объема. В результате компилятор при компилировании декомпилированого кода будут долго ругаться нехорошими словами на одинаковые идентификаторы. Но в этом случае он еще и все внутренние классы переделает в классы верхнего уровня. Т.е. исходной проблемы с видимостями имен не будет. Специально же затруднять последующую пересборку после декомпиляции стоит далеко не всгеда. Если очень нужно что-то исправить, будет проще будет дизассемблировать класс (не декомпилировать изменить, затем собрать обратно.
Оставить комментарий
Имя или ник:
Комментарий: