Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > Class -> first class object


Автор: Karadul 18.2.2012, 12:07
Как получить в яве ссылку на класс и потом вызвать через нее конструктор класса? Т.е.

Код

class Myclass {
    public Myclass()
}

myclass = Myclass;
myclass_instance = new myclass()

Автор: jk1 18.2.2012, 12:28
Код

import java.lang.reflect.InvocationTargetException;

public class Example {

    public static void main(String[] args)
            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {

        Class<Example> cl = Example.class;
        Example object = cl.getConstructor().newInstance();
        System.out.println(object);
    }
}

Автор: Karadul 18.2.2012, 13:57
А как передать параметры конструктору?

Автор: jk1 18.2.2012, 14:05
Код

import java.lang.reflect.InvocationTargetException;

public class Example {

    public Example(String param) {
        System.out.println("Initialized with: " + param);
    }

    public static void main(String[] args)
            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
        
        Class<Example> cl = Example.class;
        Example object = cl.getConstructor(String.class).newInstance("test");
    }
}

Автор: Karadul 18.2.2012, 14:13
Зачем мне все это нужно: 
Читается в цикле serversocket, принимается соединение и создается обьект с ссылкой на хендлер уже клиентского сокета в качестве параметра. Так пойдет, или можно что-то лучше придумать?

Код

while (sock = serverSocket.accept()) {
    new Thread(new SocketHandler(sock))
}


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

Автор: Samotnik 18.2.2012, 14:16
Цитата(Karadul @  18.2.2012,  12:07 Найти цитируемый пост)
Как получить в яве ссылку на класс и потом вызвать через нее конструктор класса? Т.е.

Singleton?

Автор: Karadul 18.2.2012, 14:19
Samotnik, зачем удалил-то?

Пример можно?

Автор: Samotnik 18.2.2012, 14:20
Karadul, ты же сказал не то )

Добавлено через 33 секунды
Если четсно не очень понятно что нужно. 
Рефлексия или традиционный вызов?

Автор: Karadul 18.2.2012, 14:22
Цитата(Samotnik @  18.2.2012,  14:20 Найти цитируемый пост)
Рефлексия или традиционный вызов? 

Плохо понимаю, что есть что в яве.

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

Автор: Samotnik 18.2.2012, 14:33
Я тоже плохо понимаю, что тебе нужно smile
Может как то так?
Код

class CallMe {
    
    private static CallMe callMe;
    
    public CallMe() {
        System.out.println("Empty");
    }
    
    public CallMe(int x) {
        System.out.println(x);
    }
    
    public CallMe(int x, int y) {
        System.out.println(x + " " + y);
    }
    
    public CallMe(int x, int y, int z) {
        System.out.println(x + " " + y + " " + z);
    }
    
    public static CallMe getInstance() { // метод вернет всегда ссылочную переменную типа класса
        return callMe;
    }
    
}

public class Main {
    
     public static void main(String[] args) {
        CallMe obj = CallMe.getInstance(); // получаешь, и вызываешь любые конструкторы, сколько душе угодно
        obj = new CallMe();
        obj = new CallMe(1);
        obj = new CallMe(1,2);
        obj = new CallMe(1,2,3);
     } 
   
}


Добавлено через 1 минуту и 22 секунды
По крайней мере этот код удовлетворяет условию:
Цитата(Karadul @  18.2.2012,  12:07 Найти цитируемый пост)
Как получить в яве ссылку на класс и потом вызвать через нее конструктор класса? Т.е.

smile

Автор: jk1 18.2.2012, 14:35
Цитата

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



Karadul,  а что мешает в рантайме определять? обобщение же элементарное

Код

import java.io.File;
import java.lang.reflect.InvocationTargetException;

public class Example {

    static Object[] params = new Object[]{"string", new Long(5), new File("/dev/null")};

    public Example(String str, Long count, File path) {
        System.out.println();
    }

    public static void main(String[] args)
            throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {

        Class<Example> cl = Example.class;
        Class[] types = new Class[params.length];
        for (int i = 0; i < params.length; i++){
            types[i] = params[i].getClass();
        }
        Example object = cl.getConstructor(types).newInstance(params);
    }
}

Автор: Karadul 18.2.2012, 15:02
Цитата(Samotnik @  18.2.2012,  14:33 Найти цитируемый пост)
Я тоже плохо понимаю, что тебе нужно smile
Может как то так?

Не так. Пример смотри в оппосте.

Еще точнее наверно так:
Код

Class ServerAccepter {
    public ServerAccepter (Class socketHandler, int port) {
        serverSocket.bind(port);
        while (sock = serverSocket.accept()) {
            new Thread(new socketHandler(sock))
        }
    }
}

new Thread(ServerAccepter(HandlerType1, 123));
new Thread(ServerAccepter(HandlerType2, 45));




jk1, у тебя params прописаны отдельно. Что произойдет, елси я поменяю сигнатуру конструктора?

Автор: jk1 18.2.2012, 15:07
Цитата

jk1, у тебя params прописаны отдельно. Что произойдет, елси я поменяю сигнатуру конструктора? 


Тогда и params должны поменяться. Скажите мне вот что: откуда Вы хотите брать реальные значения параметров для передачи конструктору с неизвестной сигнатурой? Они будут приходить по сети? Ну так и снимите с них в рантайме реальные типы, как я снял их со статического массива

Автор: Karadul 18.2.2012, 15:12
Типы значений - из сигнатуры, реальные значения - из new Thread(new socketHandler(sock)) в примере выше, т.е. из кода. Если они друг другу перестанут соотвествовать, что произойдет?

Автор: jk1 18.2.2012, 16:38
Цитата

Если они друг другу перестанут соотвествовать, что произойдет?


Вылетит исключение

Код

Exception in thread "main" java.lang.NoSuchMethodException: ws.Example.<init>()
    at java.lang.Class.getConstructor0(Class.java:2706)
    at java.lang.Class.getConstructor(Class.java:1657)

Автор: Karadul 19.2.2012, 02:05
Вот поэтому это решение мне не очень нравится - теряются все преимущества явы как статического языка. Нет ли чего-нибудь получше?

Автор: Karadul 19.2.2012, 04:53
Почему-то никто не подсказал про Factory. Вообще костыльность явы просто поражает.

Код

public class Consumer implements IConsumerFactory {
    @Override
    public IConsumer getConsumer(Socket sock) throws IOException {
        return (IConsumer) new Consumer(sock);
    }
    
    public class Consumer implements IConsumer {
        public Consumer(Socket sock) throws IOException {
            ....
        }
    }
}

Автор: Samotnik 19.2.2012, 13:11
Цитата(Karadul @  19.2.2012,  04:53 Найти цитируемый пост)
Почему-то никто не подсказал про Factory

Потому что нужно формировать задачу яснее  smile 
Цитата(Karadul @  19.2.2012,  04:53 Найти цитируемый пост)
Вообще костыльность явы просто поражает.

что именно является костылём? Одно из основополагающих свойств полиморфизма, когда супер класс может ссылаться на подкласс?

Автор: Karadul 19.2.2012, 13:32
Цитата(Samotnik @  19.2.2012,  13:11 Найти цитируемый пост)
Потому что нужно формировать задачу яснее  smile 

Дык куда уж. Пример кода я дал.


Цитата(Samotnik @  19.2.2012,  13:11 Найти цитируемый пост)
что именно является костылём?

То, что класс - не обьект первого класса, как и функция. А костыли - это фабрики и интерфейсы вместо замыканий.

Автор: jk1 19.2.2012, 18:45
Цитата

Дык куда уж. Пример кода я дал.


... из которого ничего не ясно. Какой-то thread, какой-то socket. Вы хотите на основании пришедших по сокету данных создать объект? Или что? Тогда какие данные будут приходить?
Вы описали бы подробно, что есть в наличии и что надо получить. Тогда и ответ был бы сразу.

Цитата

То, что класс - не обьект первого класса, как и функция.
 

Функций в java нет вообще. А класс все-таки first class object, тут Вы неправы.


Автор: Karadul 19.2.2012, 18:54
Цитата(jk1 @  19.2.2012,  18:45 Найти цитируемый пост)
А класс все-таки first class object

Но пользоваться им можно только через ректум.

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

Что еще попалось на глаза - в яве искаропки нет парсера для двоичный форматов с little endian полями, не говоря о смешаных и чего-нибудь вроде zero-terminated строк.

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