2013-10-01 17 views
5

Czy istnieje standardowa technika "rozszerzania" klasy na prywatnych konstruktorów, tak jak w przypadku większości zajęć Singleton? Dokładniej, próbuję rozszerzyć klasę java.lang.management.ThreadInfo, ponieważ dodaję DUŻO z nich do HashSet, aby kontrolować wyjątkowość. Jednak sposób, w jaki ustalam, czy dwa wątki są równe, jest inny i nie jest tożsamy ​​z domyślną implementacją metody equals().Technika rozszerzenia klasy o prywatnych konstruktorów

Rozszerzenie klasy oczywiście nie jest w tym przypadku możliwe.

uzasadnione byłoby zrobić coś podobnego klasy otoki, który akceptuje ThreadInfo w konstruktorze, a następnie ręcznie wypełnia wszystkie odpowiednie pola z wartościami, a następnie nadpisuje equals() i hashCode(), czy istnieje lepszy sposób to zrobić?

Coś w tym jest to, co zaczynam pisać, ale lepsza realizacja byłby idealny:

class ThreadInfoWrapper { 

    private ThreadInfo info; 
    ThreadInfoWrapper(ThreadInfo info) { 
     this.info = info; 
    } 

    //Populate instance variables with Thread.State, thread ID, etc.. with 
    //Getters/setters and all that other stuff 

    public boolean equals(Object o) { //Unique implementation 
    } 

    public int hashCode() { //Whatever implementation 
    } 

} 

Ale to czuje się jak bardzo okrężną drogą do osiągnięcia pewnych podstawowych funkcji. Zajrzałem do tego, a implementacje zestawów z niestandardowymi komparatorami nie istnieją w standardowej bibliotece Java. Przypuszczam, że mógłbym napisać własną implementację zestawu hasha, ale to za dużo pracy na prostą sytuację. Wszelkie spostrzeżenia byłyby pomocne.

+0

Jestem przekonany, że takich zajęć nie można przedłużać. –

+0

@JakobWeisblat W rzeczywistości mogą one zostać przedłużone, ale tylko przez ich wewnętrzne klasy, które nie są pomocne w tej sytuacji. Rozumiem, że rozszerzenie ich w moim własnym pliku klasowym nie będzie działać. Poszukuję rozsądnych alternatyw, a konkretnie sprawdzam, czy istnieją jakieś standardowe praktyki. Poszukiwania nie mogłem znaleźć. – Kon

+0

powodzenia. –

Odpowiedz

2

Przez rozszerzenie rozumie się sposób tworzenia klas pochodnych, które wykorzystują prywatny konstruktor jako konstruktor klasy super. Nie możesz, zostały one uczynione prywatnymi, aby uniemożliwić ci to. Ponieważ klasy JRE zostały napisane przez kompetentnych programistów, istnieją ku temu powody. Więc nawet jeśli mógłbyś obejść to przy użyciu sztuczek, takich jak manipulacja odbiciem lub kodowaniem bajtowym, nie powinieneś tego robić.

Ale wszystko nie jest stracone. Powinieneś i tak wolisz kompozycję od dziedziczenia. Mogą być przydatne wzory projektów dekoratora i proxy (na przykład ten jest bliski).

1

Myślę, że to, co robisz, jest uzasadnione, ponieważ istnieje niewiele innych opcji.

Alternatywą może być napisanie własnej podklasy HashMap, która używa "specjalnych" równań zamiast domyślnych. (Nie może być już apache lub guawa implementacje, aby to zrobić? - ktoś wie bezceremonialny)

(dodane później)

Ponieważ jestem leniwy, a ponieważ ThreadInfo posiada wszystkie pobierające więc jest to dość „bezpieczne”, aby odsłonić , byłbym skłonny do uczynić klasy otoki bardzo prosty, bez pobierające ani ustawiaczy:

public class ThreadInfoWrapper { 

// public so an outsider can get at the wrapped ThreadInfo 
// could be private if you are sure that will never be necessary 
public final ThreadInfo threadInfo; 

public ThreadInfoWrapper(ThreadInfo threadInfo) { 
    this.threadInfo = threadInfo; 
} 

public boolean equals(Object o) { //Unique implementation 
    // refer to threadInfo.blah... 
} 

public int hashCode() { //Whatever implementation 
    // refer to threadInfo.blah... 
} 

}

jednak to zależy od tego, co właśnie informacji używasz dla swoich rówieśników i hashcode.

+0

Dzięki za odpowiedź. Kiedy szukałem, znalazłem tę odpowiedź (http://stackoverflow.com/questions/14880450/java-hashset-with-a-custom-equality-criteria) twierdząc, że Guava "specjalnie odrzucił" mając dowolną implementację zestawu z kryteriami równości niezgodnymi z metodą 'equals()'. – Kon

+0

Wygląda na to, że wykonałeś swoje badania. Powodzenia. – user949300

Powiązane problemy