Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > вызов метода из другого пакета


Автор: Escorial 28.8.2012, 14:37
есть class A extends C { void f(){...} } А и С в одном пакете без модификаторов, есть class B { void g(){....} }  в другом пакете без модификатора. как вызвать метод g() внутри метода f(). возможно любое решения кроме установления другого модификатора доступа.

еще вопрос (класс А такой же как и в первом вопросе): class B extend A { void h(){....} } они теперь в одном пакете - как в f() вызвать h()... можно делать все что хочешь...

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

Автор: k0rvin 28.8.2012, 15:03
Прикольно, режим доступа private (который также используется поумолчанию, если никакой модификатор не указан) для того и был придуман, чтобы не позволять обращаться к таким данным извне, а его почему-то пытаются обойти, за такое по идее нужно бить палкой по рукам.

А так, через рефлексию вроде можно, https://www.google.com/search?ie=UTF-8&oe=UTF-8&q=how+to+call+private+method+from+another+package+java в помощь.

Автор: Karadul 28.8.2012, 15:23
По умолчанию protected же?

Автор: Stolzen 28.8.2012, 16:05
Цитата(Karadul @  28.8.2012,  16:23 Найти цитируемый пост)
По умолчанию protected же? 

Нет, правильнее будет назвать package-private, protected несколько шире

Автор: Escorial 28.8.2012, 21:42
По умолчанию внутри пакета, без доступа наследникам.
Вообщем спасибо, что откликнулись буду дальше искать.

Автор: Pawl 2.9.2012, 21:15
Честно, не совсем понял, зачем класс А должен быть наследником С, ну да ладно. Вот каким может быть ответ на первую часть Вашего вопроса:
Код

package a;

class C {
    void f() {
        System.out.println("in C");
    }
}

Код

package b;

public class B {
    void g() {
        System.out.println("in B");
    } 
}

Код

package a;

import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import b.B;

class A extends C {
    void f() {
        B bb = new B();
        try {
            Method privatG = B.class.getDeclaredMethod("g");
            privatG.setAccessible(true);        
            privatG.invoke(bb);
        } catch (IllegalAccessException | InvocationTargetException | IllegalArgumentException |
                NoSuchMethodException e) {
            System.out.println(e.getMessage());
        }        
    }
    
    public static void main(String[] args) {
        new A().f();
    }
}
По-поводу второй части вопроса. Если можно делать "все, что хочешь", то в чем же тогда проблема? 

Автор: Escorial 3.9.2012, 13:59
спасибо за ответ. я не знаю будет ли работать класс А если убрать public модификатор у класса В, так как вся проблема и касалась того, как обойти модификатор доступа.

Автор: Pawl 3.9.2012, 20:22
Цитата(Escorial @  3.9.2012,  13:59 Найти цитируемый пост)
я не знаю будет ли работать класс А если убрать public модификатор у класса В,

мда, не будет... Строчку с названием и сигнатурой метода в этом случае получить можно так:
Код

class A extends C {
    void f() {
        try {
            Method privatG = Class.forName("b.B").getDeclaredMethod("g");
            privatG.setAccessible(true);        
            System.out.println(privatG.toGenericString());
        } catch (Exception e) {
            e.printStackTrace();
        }        
    }

А как этот метод вызвать... Сдаюсь! smile
Вот, пришла в голову мысль: а в ТЗ ничего не было сказано про модификатор доступа конструктора класса В? Если сделать в В public-конструктор, вызвать его метод g можно так:
Код

package b;

class B {
    public B() {
    }
    
    void g() {
        System.out.println("aha!");
    } 
}

Код

package a;

import java.lang.reflect.Method;
import java.lang.reflect.Constructor;

class A extends C {
    void f() {
        try {
            Constructor constrB = Class.forName("b.B").getConstructor();
            constrB.setAccessible(true);
            Method privatG = Class.forName("b.B").getDeclaredMethod("g");
            privatG.setAccessible(true);
            privatG.invoke(constrB.newInstance());    
        } catch (Exception e) {
            e.printStackTrace();
        }        
    }
    
    public static void main(String[] args) {
        new A().f();
    }
}

Автор: Escorial 7.9.2012, 12:49
возможно вы правы. просто тогда находит мысль - зачем все это делать - не легче тогда сделать класс публичный?)) - вообщем я насчет этих вопросов себе создал мысль - что люди просто хотят поднять статус собеседования - задавая каверзные вопросы - решения которых смысла не имеет)
Спасибо за ответ и помощь - буду для себя знать что можно с помощью интерфесов Conctructor и Method получить напрямую доступ к конструктору и методу н есоздавая обьект класса. - если я правильно понял то что вы предлдожили.

Автор: Pawl 8.9.2012, 10:40
Цитата(Escorial @  7.9.2012,  12:49 Найти цитируемый пост)
Спасибо за ответ и помощь - буду для себя знать что можно с помощью интерфесов Conctructor и Method получить напрямую доступ к конструктору и методу н есоздавая обьект класса.

Не за что smile  На самом деле, объект класса для вызова его метода все-же создается. Обратите внимание на строку:
Код

constrB.newInstance();

Цитата

Uses the constructor represented by this Constructor object to create and initialize a new instance of the constructor's declaring class

В java нельзя вызвать метод класса, не создавая объект этого класса, если, конечно, этот метод не static.

Автор: Escorial 10.9.2012, 22:20
Спасибо за уточнение:)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)