ďťż
 
Problem klasa generyczna - hello world. ďťż
 
Problem klasa generyczna - hello world.
Zobacz wiadomości
 
Cytat
A gdyby tak się wedrzeć na umysłów górę, / Gdyby stanąć na ludzkich myśli piramidzie, / I przebić czołem przesądów chmurę, / I być najwyższą myślą wcieloną. . . Juliusz Słowacki, Kordian
Indeks BCB i MySQL subiekt gt fototapeta
 
  Witamy

Problem klasa generyczna - hello world.



Seweryn =?ISO-8859-2?Q?Habdank=2DWojew=F3dzki?= - 04-04-2006 00:09
Problem klasa generyczna - hello world.
  Witam

Mam taką klasę:

public class generic_test<T> {

public T elem;

public generic_test(T elem) {
this.elem = elem;
}
}

Oraz

public class Main {

public Main() {
}

public static void main(String[] args) {
generic_test<Integer> elem1;
generic_test<Double> elem2;
// generic_test<int> elem0; // *
}
}

I mam pytania:

1. Dlaczego nie działa linijka oznaczona "// *", gdzie w specyfikacji jest to
wytłumaczone, jasne jest dla mnie, że typ int nie daje referencji i to pewnie
nie będzie działać dla żadnego POD'a. Ale gdzie to jest napisane w opisie
języka, aby poczytać szerzej na ten temat. Czy można liczyć na jakieś
"boxingi" jeżeli ktoś poda double zamiast Double w kontekście klas
generycznych?

2. Jak zrobic specjalizację dla różnych typów. Chodzi mi o sytuację, że jeżeli
mam typ T który jest czymś ala macierz to czasem doniego jest dostęp poprzez
np. get(i,j), czasem inaczej a zatem chciałbym mieć generyczny wraper do
pobierania elementów z np. macierzy. Co ogólnie jest ważne jeżeli kod dla
poszczególnych typów jest inny.

Pozdrawiam.

--

|\/\/| Seweryn Habdank-Wojewódzki
`\/\/





Grzegorz Głowaty - 04-04-2006 00:10

 
Użytkownik "Seweryn Habdank-Wojewódzki" <habdank@gmail.com> napisał w
wiadomości news:e0r464$juq$1@tkdami.pl...
> Witam
>
> Mam taką klasę:
>
> public class generic_test<T> {
>
> public T elem;
>
> public generic_test(T elem) {
> this.elem = elem;
> }
> }
>
> Oraz
>
> public class Main {
>
> public Main() {
> }
>
> public static void main(String[] args) {
> generic_test<Integer> elem1;
> generic_test<Double> elem2;
> // generic_test<int> elem0; // *
> }
> }
>
> I mam pytania:
>
> 1. Dlaczego nie działa linijka oznaczona "// *", gdzie w specyfikacji jest
> to
> wytłumaczone, jasne jest dla mnie, że typ int nie daje referencji i to
> pewnie
> nie będzie działać dla żadnego POD'a. Ale gdzie to jest napisane w opisie
> języka, aby poczytać szerzej na ten temat. Czy można liczyć na jakieś
> "boxingi" jeżeli ktoś poda double zamiast Double w kontekście klas
> generycznych?

Zaczynajac od konca, podajac double do typu sparametryzowanego jako Double
zadziala autoboxing.
Typy generyczne mozna parametryzowac tylko nazwami klas.

> 2. Jak zrobic specjalizację dla różnych typów. Chodzi mi o sytuację, że
> jeżeli
> mam typ T który jest czymś ala macierz to czasem doniego jest dostęp
> poprzez
> np. get(i,j), czasem inaczej a zatem chciałbym mieć generyczny wraper do
> pobierania elementów z np. macierzy. Co ogólnie jest ważne jeżeli kod dla
> poszczególnych typów jest inny.

Nie rozumiem pytania.

greg




Seweryn =?ISO-8859-2?Q?Habdank=2DWojew=F3dzki?= - 05-04-2006 00:04

  Witam

Grzegorz Głowaty wrote:

> Zaczynajac od konca, podajac double do typu sparametryzowanego jako Double
> zadziala autoboxing.

Ok.

> Typy generyczne mozna parametryzowac tylko nazwami klas.

Aha. A wiesz gdzie to jest wyspecyfikowane? Jak nie wiesz to nie szukaj.

>> 2. Jak zrobic specjalizację dla różnych typów. Chodzi mi o sytuację, że
>> jeżeli
>> mam typ T który jest czymś ala macierz to czasem doniego jest dostęp
>> poprzez
>> np. get(i,j), czasem inaczej a zatem chciałbym mieć generyczny wraper do
>> pobierania elementów z np. macierzy. Co ogólnie jest ważne jeżeli kod dla
>> poszczególnych typów jest inny.
>
> Nie rozumiem pytania.

Załóżmy, że jak było poprzednio:

public class generic_test<T> {

public T elem;

public generic_test(T elem) {
System.out.println("Something");
// * do_something_on_Double();
// ** do_something_completely_else_on_Integer();
this.elem = elem;
}
}

Tyle, że "Something" chcę mieć inne dla Double inne dla Integer. Albo linijki
poniżej chcę mieć różne czyli dla Double uruchamiam // * a dla Integer // *.

Chyba że to tylko mogę zrobić poprzez ręczne sprawdzanie typu?

Pozdrawiam i dziękuję za zainteresowanie.

--

|\/\/| Seweryn Habdank-Wojewódzki
`\/\/




Piotr Kobzda - 05-04-2006 00:04

  Seweryn Habdank-Wojewódzki wrote:

>>Typy generyczne mozna parametryzowac tylko nazwami klas.
>
> Aha. A wiesz gdzie to jest wyspecyfikowane? Jak nie wiesz to nie szukaj.

JLS3 4.4.

>
>
>>>2. Jak zrobic specjalizację dla różnych typów. Chodzi mi o sytuację, że
>>>jeżeli
>>>mam typ T który jest czymś ala macierz to czasem doniego jest dostęp
>>>poprzez
>>>np. get(i,j), czasem inaczej a zatem chciałbym mieć generyczny wraper do
>>>pobierania elementów z np. macierzy. Co ogólnie jest ważne jeżeli kod dla
>>>poszczególnych typów jest inny.
>>
>>Nie rozumiem pytania.
>
>
> Załóżmy, że jak było poprzednio:
>
> public class generic_test<T> {
>
> public T elem;
>
> public generic_test(T elem) {
> System.out.println("Something");
> // * do_something_on_Double();
> // ** do_something_completely_else_on_Integer();
> this.elem = elem;
> }
> }
>
> Tyle, że "Something" chcę mieć inne dla Double inne dla Integer. Albo linijki
> poniżej chcę mieć różne czyli dla Double uruchamiam // * a dla Integer // *.

W Javie obowiązuje tzw. wymazywanie typów generycznych (type erasure)
przez co kod generyczny nie wie jakim konkretnie typem został
sparametryzowany.

>
> Chyba że to tylko mogę zrobić poprzez ręczne sprawdzanie typu?

Tak. Twój przykład mógłby wyglądać tak:

public class GenericTest<T> {

public T elem;

public GenericTest(T elem) {
System.out.println("Something");
if (Double.class.isInstance(elem)) {
// * do_something_on_Double();
} else if (Integer.class.isInstance(elem)) {
// ** do_something_completely_else_on_Integer();
}
this.elem = elem;
}
}

Sposób ogólny, to jawnie przekazać klasie generycznej typu parametru
jakim została sparametryzowana (czyli np. instancję Class<T>), co jednak
w Twoim przykładzie nie wydaje się konieczne.

PS. Stosuj właściwie Javie konwencje nazewnictwa.

piotr





Seweryn =?ISO-8859-2?Q?Habdank=2DWojew=F3dzki?= - 05-04-2006 00:04

  Witam

Piotr Kobzda wrote:

> JLS3 4.4.

Dziękuję to jest bardzo dobra odpowiedź.

> W Javie obowiązuje tzw. wymazywanie typów generycznych (type erasure)
> przez co kod generyczny nie wie jakim konkretnie typem został
> sparametryzowany.

Rozumiem.

>> Chyba że to tylko mogę zrobić poprzez ręczne sprawdzanie typu?
>
> Tak. Twój przykład mógłby wyglądać tak:
>
> public class GenericTest<T> {
>
> public T elem;
>
> public GenericTest(T elem) {
> System.out.println("Something");
> if (Double.class.isInstance(elem)) {
> // * do_something_on_Double();
> } else if (Integer.class.isInstance(elem)) {
> // ** do_something_completely_else_on_Integer();
> }
> this.elem = elem;
> }
> }

Czyli tak jak myślałem ręczne sprawdzenie typu.

> Sposób ogólny, to jawnie przekazać klasie generycznej typu parametru
> jakim została sparametryzowana (czyli np. instancję Class<T>), co jednak
> w Twoim przykładzie nie wydaje się konieczne.

W tym oczywiście, że nie, ale projektuję coś cięższego niż klasę generyczną dla
Integer i Double, więc nie wiem czy i Class<T> nie będę używał.

> PS. Stosuj właściwie Javie konwencje nazewnictwa.

Czy masz na myśli GenericTest vs. generic_test?

Tak, stosuję w programach, ale jakoś tutaj pisałem szybko i przez to, że teraz
dużo koduje w C++ napisałem w notacji z C++.

Nota bene jest mocna ekipa ludzi, którzy w C++ używają notacji Javy - IMHO to
jest kwestia przyzwyczajeń i ustaleń w grupie programistów, oczywiście w Javie
SUN narzuca pewną konwencję, której nie krytykuję, bo upodobań się nie
krytykuje.

Chyba, że chodzi o co innego, to prosze mnie oświecić.

Pozdrawiam.

--

|\/\/| Seweryn Habdank-Wojewódzki
`\/\/




Brzezi - 05-04-2006 00:04

  wto, 04 kwi 2006 o 12:04 GMT, Seweryn Habdank-Wojewódzki napisał(a):

> Czyli tak jak myślałem ręczne sprawdzenie typu.

Tego nie da sie obejsc, bo niby jak? musisz wiedziec jaki typ jest uzywany,
i zaleznie od niego "decydowac"

jedyna wariacja metody Piotra jaka jeszcze widze, to modyfikacja tego do
wzorca Factory, robisz fabryke, za jej pomoca podajac typ, budujesz
wyspecjalizowana klase...

Pozdrawiam
Brzezi
--
[ E-mail: brzezi@enter.net.pl ][ ]
[ Ekg: #3781111 ][ ]
[ LinuxUser: #249916 ][ ]




Seweryn =?ISO-8859-2?Q?Habdank=2DWojew=F3dzki?= - 05-04-2006 00:04

  Witam

Brzezi wrote:

> Tego nie da sie obejsc, bo niby jak? musisz wiedziec jaki typ jest uzywany,
> i zaleznie od niego "decydowac"

Tak tylko pytałem bo w C++ da się to inaczej zrobić, więc wolałem zapytać i
upewnić się.

> jedyna wariacja metody Piotra jaka jeszcze widze, to modyfikacja tego do
> wzorca Factory, robisz fabryke, za jej pomoca podajac typ, budujesz
> wyspecjalizowana klase...

Masz rację, tylko, że Abstract Factory ma jedną wadę potrzebuje tworzyć objekty
mające wspólną klasę bazową, a to jest dla mnie kłopotliwe, bo wymusiłoby to
tworzenie niezbyt rozsądnego drzewa klas.

Pozdrawiam.

--

|\/\/| Seweryn Habdank-Wojewódzki
`\/\/




Brzezi - 05-04-2006 00:04

  wto, 04 kwi 2006 o 17:12 GMT, Seweryn Habdank-Wojewódzki napisał(a):

>> Tego nie da sie obejsc, bo niby jak? musisz wiedziec jaki typ jest uzywany,
>> i zaleznie od niego "decydowac"
> Tak tylko pytałem bo w C++ da się to inaczej zrobić, więc wolałem zapytać i
> upewnić się.

a mozesz podac przyklad? tak z ciekawosci pytam co masz na mysli...

>> jedyna wariacja metody Piotra jaka jeszcze widze, to modyfikacja tego do
>> wzorca Factory, robisz fabryke, za jej pomoca podajac typ, budujesz
>> wyspecjalizowana klase...
>
> Masz rację, tylko, że Abstract Factory ma jedną wadę potrzebuje tworzyć objekty
> mające wspólną klasę bazową, a to jest dla mnie kłopotliwe, bo wymusiłoby to
> tworzenie niezbyt rozsądnego drzewa klas.

Mowilem ogolnie o Fabryce, nie wyszczegolnilem tam Abstract Factory,
zasugerowalem tylko ogolna mysl :)

Pozdrawiam
Brzezi
--
[ E-mail: brzezi@enter.net.pl ][ brzezi:~# uptime ]
[ Ekg: #3781111 ][ 17:16:10 up 2 days, 23:44, 1 user, ]
[ LinuxUser: #249916 ][ load average: 1.45, 1.25, 1.17 ]




Seweryn =?ISO-8859-2?Q?Habdank=2DWojew=F3dzki?= - 05-04-2006 00:04

  Witam

Brzezi wrote:

> wto, 04 kwi 2006 o 17:12 GMT, Seweryn Habdank-Wojewódzki napisał(a):
>> Tak tylko pytałem bo w C++ da się to inaczej zrobić, więc wolałem zapytać i
>> upewnić się.
>
> a mozesz podac przyklad? tak z ciekawosci pytam co masz na mysli...

przykład problemu:

//ładniej jest zrobić z seterami i geterami tak jak w opisie generyków u SUN'a,
//ale nie chce mi się pisać.
public class Pair<F, S> {
public F first;
public S second;
}

public Kontener < ElementType, IndexType > {
public ElementType getElement ( IndexType index ) {
//tutaj muszę rozpoznawać IndeksType załóżmy,
//że mamy Integer i Pair<Integer,Integer>
//Ale kiedy tego jest więcej to kod staje się przyciężkawy
};
}

Wersja w C++

template<typename F, typename S>
struct Pair {
F first;
S second;
}

//działanie domyślne - można też wsadzić do środka rozpoznawanie typów w
połączeniu z działaniem domyślnym,
//ale można inaczej jak niżej
typename < ElementType, IndexType >
struct Kontener {
ElementType getElement ( IndexType index )//tu może być ";"
//albo w "{}" domyślne działanie
}

//specjalizacja szablonu dla indeksu Integer
template < typename ElementType >
struct Kontener < ElementType, Integer> {
ElementType getElement ( Integer index )
{
//funkcjonalność dla Integer
}
}

//specjalizacja szablonu dla indeksu Pair<Integer,Integer>
template < typename ElementType >
struct Kontener < ElementType, Pair<Integer,Integer > > {
ElementType getElement ( Pair<Integer,Integer > index ){
//funkcjonalność dla Pair<Integer, Integer>
}
}

Jeśli w kodzie będą specjalizacje jak tutaj działanie domyślne będzie
"nadpisane", klasa zostanie przeładowana ze względu na typy. To powoduje, że
jeżeli nie znam się na jakims indeksie to nie muszę jego uwzględniać w swojej
klasie a jak ktoś uzna to za stosowne sam sobie może go dopisać.

To jest prościutki przykład i na pewno można to zrobić na tysiąc innych
sposobów, gorzej jest kiedy zaczynamy iść pod górę i zamiast Integer i
Pair<Integer,Integer> mamy jakieś pogmatwane kontenery np.
Hashtable< ElementType, ArrayList < ElementType > >.
Przyczym zarówno Hashtable może być innym kontenerem jak i ArrayList może być
czyś innym. I ten wewnętrzny if zrobi się koszmarny, choć pewnie da się go
rozczłonkować, na podprzypadki i funkcjonalnośc powyżucac do innych klas.

Pozdrawiam.

--

|\/\/| Seweryn Habdank-Wojewódzki
`\/\/




Piotr Lipski - 11-04-2006 00:24

  Czy poniższy kod jest tym co chciałeś osiągnąć?

PL

public class Container<E, I extends Index<E, I>> {
public static void main(String[] args) throws Exception {
{
Container<String, SimpleIndex<String>> h = Container();
h.getElement(new SimpleIndex<String>());
}

{
Container<Integer, PairIndex<Integer>> h = Container();
h.getElement(new PairIndex<Integer>());
}
}

E getElement(I index) { return index.accept(this); }

static <E, I extends Index<E, I>> Container<E, I> Container() { return new
Container<E, I>(); }

E get(SimpleIndex<E> index) {
System.out.println("SimpleIndex<E>");
return null;
}

E get(PairIndex<E> index) {
System.out.println("PairIndex<E>");
return null;
}
}

interface Index<E, I extends Index<E, I>> {
public E accept(Container<E, I> h);
}

class SimpleIndex<E> implements Index<E, SimpleIndex<E>> {
public E accept(Container<E, SimpleIndex<E>> h) { return h.get(this); };
}

class PairIndex<E> implements Index<E, PairIndex<E>> {
public E accept(Container<E, PairIndex<E>> h) { return h.get(this); };
}




Seweryn =?ISO-8859-2?Q?Habdank=2DWojew=F3dzki?= - 12-04-2006 00:37

  Witam

Piotr Lipski wrote:

> Czy poniższy kod jest tym co chciałeś osiągnąć?

Jeszcze nie wiem, ale dziękuję bardzo za całkiem zgrabyny kawałek kodu.

Pozdrawiam.

--

|\/\/| Seweryn Habdank-Wojewódzki
`\/\/




Piotr Kobzda - 16-04-2006 01:01

  Seweryn Habdank-Wojewódzki wrote:

> Piotr Lipski wrote:
>
>>Czy poniższy kod jest tym co chciałeś osiągnąć?
>
> Jeszcze nie wiem, ale dziękuję bardzo za całkiem zgrabyny kawałek kodu.

A może poniższe bardziej Twym potrzebom odpowiada?

piotr

public class Container<E, I> {

public static void main(String[] args) {
{
Container<String, Integer> c =
Container.newIntegerIndexedInstance();
c.getElement(3);
}
{
Container<String, Pair<Long, Short>> c =
Container.newPairIndexedInstance();
c.getElement(new Pair<Long, Short>());
}
}

public interface IndexedAccess<E, I> {
E get(Container<E, I> container, I index);
}

private IndexedAccess<E, I> ia;

public Container(IndexedAccess<E, I> ia) {
this.ia = ia;
}

public E getElement(I index) {
return ia.get(this, index);
}

public static <E> Container<E, Integer>
newIntegerIndexedInstance() {
return new Container<E, Integer>(
new IndexedAccess<E, Integer>() {
public E get(Container<E, Integer> container, Integer
index) {
System.out.println(container +".getElement("+ index +
")");
return null;
}
});
}

public static <E, F, S> Container<E, Pair<F, S>>
newPairIndexedInstance() {
return new Container<E, Pair<F, S>>(
new IndexedAccess<E, Pair<F, S>>() {
public E get(Container<E, Pair<F, S>> container, Pair<F,
S> index) {
System.out.println(container +".getElement("+ index +
")");
return null;
}
});
}

}
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • effulla.pev.pl
  • comp
    [MSSQL2000] Problem z =?ISO-8859-2?Q?tabel=B1/indeksem/zapytanie?==?ISO-8859-2?Q?m_czy_b=B3=B1d_w_bazie_danych=2E=2E=2E?= mysql i mysql-front, problem String line; if (line=="cos"){...}....problem Problemy z =?ISO-8859-2?Q?instalacj=B1_PostgreSQL_na_syste?==?ISO-8859-2?Q?mach_Windows?= [postgres] Problem z =?ISO-8859-2?Q?zmian=B1_struktury_i_z?==?ISO-8859-2?Q?ale=BFno=B6ciami=2E?= [oracle] =?ISO-8859-2?Q?zmia=BFd=BFony_przez_problem=3A_za?==?ISO-8859-2?Q?pytanie_do_hierarchi?= Problem z wartościami w MySQL :( [ MySQL and ASP and VBScript ] [PGSQL] czy ktos mial problemy z initdb pgsql 8.1 ? [MySQL] Problem z zapisem danych w bazie danych Problem z mysql - can't connect to MySQL/nietypowo...
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • tejsza.htw.pl
  • Cytat

    Decede mihi sole - nie zasłaniaj mi słonca.
    Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści
    Hoc fac - tak czyń.
    A tergo - od tyłu; z tyłu.
    I czarne włosy posiwieją. Safona

    Valid HTML 4.01 Transitional

    Free website template provided by freeweblooks.com