powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Перечесляемые типы, наследование.
14 сообщений из 14, страница 1 из 1
Перечесляемые типы, наследование.
    #37634648
Devider
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Коллеги, есть группа однотипных enum'ов такого плана:
Код: java
1.
2.
3.
4.
5.
6.
	public enum AT { 
		VALUE1('1'), 
		VALUE2('2'); 
		private AT(char at) { this.at = at; } 
		final char at; 
	} 


и есть такой вот метод, который пишет массив этих енумов в, допустим, json.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
	// Enums
	public static <E extends Enum<E>> void writeEnums(String fieldName, EnumSet<E> set, JsonGenerator j) throws JsonGenerationException, IOException {
		j.writeFieldName(fieldName);
		j.writeStartArray(); 
		if (set != null) {
			for (E i : set) {
				j.writeString(i.toString());
			}
		}
		j.writeEndArray();
	}


Суть проблемы в то, что toString() пишет "VALUE1" вместо "1". Мы, конечно, можем его переопределить и сделать
Код: java
1.
2.
3.
4.
		@Override
		public String toString() {
			return String.valueOf(at);
		}


НО:
1. начальство сказало, что не кошерно юзать toString() для небогоугодных целей.
2. и главное: иногда надо возвращать не String а int или на крайняк Integer.
Посему хочется написать что-то типа:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
	public interface Jsonable<T> {
		T getValue();
	}
// ...........
	public enum AT implements Jsonable<Integer> { 
		VALUE1(1), 
		VALUE2(2); 
		private AT(int at) { this.at = at; } 
		final int at; 
		@Override
		public Integer getValue() {
			return at;
		}
	} 


Вопросы:
1. как изменить сигнатуру writeEnums() чтобы указать, чтобы там иметь возможность вызывать getValue()?
2. как-то можно это все облагородить? Выглядит код достаточно коряво. В частности, j.writeString(i.getValue()); придется заменять на j.writeInteger(i.getValue()); в случае интов, а соответственно, придется, видимо, делать методы writeEnumsAsString() и writeEnumsAsNumbers() (Разница в том, что в json значения должны уходить в кавычках или без в зависимости от типа).
...
Рейтинг: 0 / 0
Перечесляемые типы, наследование.
    #37634917
Miha_S7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Devider,


Код: java
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.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
import java.util.*;

public class Test {

    public static interface Xintf {
        
        int getVal();
        
    }

    public static enum Tenum implements Xintf {
        
        CODE1(1), 
        CODE5(5), 
        CODE7(7), 
        CODE10(10);
        
        private final int val;
        
        private Tenum(int val) {
            
            this.val = val;
            
        }
        
        @Override public int getVal() {
            
            return val;
        
        }
    
    }
    
    
    private <E extends Enum<E> & Xintf> void method(Class<E> cls) {
        
        EnumSet<E> es = EnumSet.allOf(cls);
        
        for (E i : es) {
            System.out.println(i.toString());
            System.out.println(i.getVal());
        }
        
    }
    

    public static void main(String[] args) {
        
        Test inst = new Test();
        
        inst.method(Tenum.class);
        
        System.out.println("Done");
        
    }

}


...
Рейтинг: 0 / 0
Перечесляемые типы, наследование.
    #37634921
Miha_S7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Miha_S7,

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
D:\>java Test
CODE1
1
CODE5
5
CODE7
7
CODE10
10
Done
...
Рейтинг: 0 / 0
Перечесляемые типы, наследование.
    #37635227
Devider
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Miha_S7,

int getVal() это не совсем то что нужно. Метож может возвращать и стринг. Поэтому я и пишу public interface Jsonable<T> .
...
Рейтинг: 0 / 0
Перечесляемые типы, наследование.
    #37635238
Devider
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А, там &..., а я запятую ставил.. ))
В общем, метод стал:
Код: java
1.
public static <E extends Enum<E> & IJsonable<String>> void writeEnumsAsString(String fieldName, EnumSet<E> set, JsonGenerator j) throws JsonGenerationException, IOException 
...
Рейтинг: 0 / 0
Перечесляемые типы, наследование.
    #37635258
Devider
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ой, гоню я.. не то.. (
...
Рейтинг: 0 / 0
Перечесляемые типы, наследование.
    #37635294
Miha_S7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Devider,

вам надо что-то типа такого?


Код: java
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.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
import java.util.*;
import java.lang.reflect.*;

public class Test {

    public static interface Xintf<T> {
        T getVal();
        Class<?> getXintfGCls();
    }

    public static enum Tenum implements Xintf<Integer> {
        
        CODE1(1), 
        CODE5(5), 
        CODE7(7), 
        CODE10(10);
        
        private final Integer val;
        
        private Tenum(Integer val) {
            this.val = val;
        }
        
        @Override public Integer getVal() {
            return val;
        }
        
        @Override public Class<?> getXintfGCls() {
            return Integer.class;      
        }
    }
    
    public static enum Tenum2 implements Xintf<String> {
        
        CODE1("1"), 
        CODE5("5"), 
        CODE7("7"), 
        CODE10("10");
        
        private final String val;
        
        private Tenum2(String val) {
            this.val = val;
        }
        
        @Override public String getVal() {
            return val;        
        }
        
        @Override public Class<?> getXintfGCls() {

            return String.class;      
        }
    }
    
    private <E extends Enum<E> & Xintf<?>> void method(Class<E> cls) {
        EnumSet<E> es = EnumSet.allOf(cls);
        for (E i : es) {
            if(i.getXintfGCls().equals(Integer.class)) {
                System.out.println("write Integer: " + i.getVal());
            }
            else if(i.getXintfGCls().equals(String.class)) {
                System.out.println("write String: " + i.getVal());
            }
        }
    }
    
    public static void main(String[] args) {
        Test inst = new Test();
        inst.method(Tenum.class);
        inst.method(Tenum2.class);
        System.out.println("Done");
    }
}


...
Рейтинг: 0 / 0
Перечесляемые типы, наследование.
    #37635477
Miha_S7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Miha_S7,

добавлю: и использовать полиморфизм для writeString()
...
Рейтинг: 0 / 0
Перечесляемые типы, наследование.
    #37635685
Miha_S7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Miha_S7,

не, полиморфизм не сработает:

Код: java
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.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
import java.util.*;
import java.lang.reflect.*;

public class Test {

    public static interface Xintf<T> {
        T getVal();
    }

    public static enum Tenum
    implements Xintf<Integer> 
    {
        
        CODE1(1), 
        CODE5(5), 
        CODE7(7), 
        CODE10(10);
        
        private final Integer val;
        
        private Tenum(Integer val) {
            this.val = val;
        }
        
        @Override public Integer getVal() {
            return val;
        }
    }
    
    public static enum Tenum2
    implements Xintf<String> 
    {
        
        CODE1("1"), 
        CODE5("5"), 
        CODE7("7"), 
        CODE10("10");
        
        private final String val;
        
        private Tenum2(String val) {
            this.val = val;
        }
        
        @Override public String getVal() {
            return val;        
        }
    }
    
    public static class JCls {
        
        public static void write(String v) {
            System.out.println("write String: " + v);
        }
        
        public static void write(Integer v) {
            System.out.println("write Integer: " + v);
        }
        
    }
    
    private <K, E extends Enum<E> & Xintf<K>> 
    void method(Class<E> cls, Class<K> cls2)
    {
        EnumSet<E> es = EnumSet.allOf(cls);
        for (E i : es)
            JCls.write(i.getVal()); // полиморфизм не срабатывает
    }
    
    public static void main(String[] args) {
        Test inst = new Test();
        
        inst.method(Tenum.class,  Integer.class);
        inst.method(Tenum2.class, String.class);
        
        System.out.println("Done");
    }
}

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
D:\>javac Test.java
Test.java:68: cannot find symbol
symbol  : method write(K)
location: class Test.JCls
            JCls.write(i.getVal()); // полиморфизм не срабатывает
                ^
1 error

почему - пока не знаю
...
Рейтинг: 0 / 0
Перечесляемые типы, наследование.
    #37641804
Miha_S7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
вообщем всё из-за такой штуки, как Type Erasure . Как раз из-за него нельзя делать полиморфные методы для generic типов. В связи с этим лучше всего переделать JCls:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
public class JCls
{
    public static void write(Object v) {
        if(v instanceof String) {
            writeS(String.class.cast(v));
        }
        else if(v instanceof Integer) {
            writeI(Integer.class.cast(v));
        }
        else {
            throw new RuntimeException("Unknown type " + v);
        }
    }
    public static void writeS(String v) {
        System.out.println("write String: " + v);
    }
    public static void writeI(Integer v) {
        System.out.println("write Integer: " + v);
    }
}


жаль, конечно, что нельзя все проверки в compile time перенести, зато обратная совместимость :-)
...
Рейтинг: 0 / 0
Перечесляемые типы, наследование.
    #37642127
Devider
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо большое.
Последний, надеюсь, вопрос по этой теме.
теперь обратная задача.
Сделал метод
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
	public static <T extends Enum<T> & Jsonable<?>> T parseEnum(Class<T> clazz, String value) {
		T returnValue = null;
		for (final T element : EnumSet.allOf(clazz)) {
			if (element.getValue().toString().equals(value)) { // getValue() это как раз из Jsonable
				returnValue = element;
			}
		}
		return returnValue;
	}


и оно работает. Далее надо парсить коллекцию этих енумов в EnumSet. Например
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
	public static <T extends Enum<T> & Jsonable<?>> EnumSet<T> parseEnumSet(Class<T> clazz, String...values) {
		List<T> list = new ArrayList<T>(); // из листа нам нужен метод add. Костыль, но альтернативы не вижу.
		for (String s : values){
			T e = (T) parseEnum(clazz.getClass(), s); // А вот тута ошибка
			list.add(e);
		}
		EnumSet es = EnumSet.copyOf(list);
		return es;
	}



И ошибка выглядит так:
Multiple markers at this line
- Cannot cast from capture#2-of ? extends Class to T
- Bound mismatch: The generic method parseEnum(Class<T>, String) of type AbstractDeserializer is not applicable for the arguments (Class<capture#2-of ? extends
Class>, String). The inferred type capture#2-of ? extends Class is not a valid substitute for the bounded parameter <T extends Enum<T> & Jsonable<?>>
Собственно, что вообще имеется ввиду?
...
Рейтинг: 0 / 0
Перечесляемые типы, наследование.
    #37642148
Miha_S7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
[quot Devider]
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
	public static <T extends Enum<T> & Jsonable<?>> EnumSet<T> parseEnumSet(Class<T> clazz, String...values) {
		List<T> list = new ArrayList<T>(); // из листа нам нужен метод add. Костыль, но альтернативы не вижу.
		for (String s : values){
			T e = (T) parseEnum(clazz.getClass(), s); // А вот тута ошибка
			list.add(e);
		}
		EnumSet es = EnumSet.copyOf(list);
		return es;
	}


clazz.getClass() - clazz уже типа Class
...
Рейтинг: 0 / 0
Перечесляемые типы, наследование.
    #37642167
Devider
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Miha_S7,

Туплю. Еще раз большое спасибо!
...
Рейтинг: 0 / 0
Перечесляемые типы, наследование.
    #37642237
Miha_S7
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Devider,

и там коммент ещё пропустил:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
public static <T extends Enum<T> & Jsonable<?>> EnumSet<T> parseEnumSet(Class<T> clazz, String...values) {
    //List<T> list = new ArrayList<T>(); // из листа нам нужен метод add. Костыль, но альтернативы не вижу.
    EnumSet<T> es = EnumSet.noneOf(clazz);
    for (String s : values){
        T e = (T) parseEnum(clazz.getClass(), s); // А вот тута ошибка
        es.add(e);
    }
    return es;
}
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Перечесляемые типы, наследование.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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