2010-04-16 15 views
6

Załóżmy, że mam klasę singleton w zewnętrznej bibliotece do mojej aplikacji. Ale wciąż mogę tworzyć wystąpienia tej konkretnej klasy za pomocą refleksji. Podobny do tego:Framework i ochrona odbić Java

Class clas = Class.forName(Private.class.getName()); 

    for(Constructor c : clas.getDeclaredConstructors()){ 
     c.setAccessible(true); 
     Private p = (Private) c.newInstance(); 
     System.out.println(p); 
    } 

Jak mogę ograniczyć to? .

Dzięki J

+0

AH bóle singletons .. –

+2

Zobacz także: http://stackoverflow.com/questions/2481862/how-to-limit-setaccessible-to-only-legitimate-uses – polygenelubricants

Odpowiedz

6

Za pomocą SecurityManager i sterowanie sterowanie ReflectPermission("suppressAccessChecks") (example).

Menedżer bezpieczeństwa wpływa jednak na wydajność i rzadko jest używany po stronie serwera.

+0

[Jak duży jest wpływ na wydajność?] (http://stackoverflow.com/questions/14903423/security-manager-rarely-used-on-server) –

0

Krótka historia: nie można.

Do każdego konstruktora, zarówno publicznego, jak i prywatnego, można uzyskać dostęp poprzez odbicie i można go użyć do utworzenia instancji nowego obiektu.

Będziesz musiał odwołać się do innych metod, takich jak SecurityManager.

0

Nie sądzę, że można to ograniczyć.

Jest oczywiście niebezpieczną/wątpliwą praktyką używanie refleksji w celu uzyskania dostępu do prywatnych części innych osób (snicker), ale czasami jest to konieczne z powodu różnych typów narzędzi i aplikacji.

1

Jeśli mówimy o pojedynczych w szczególności: to jest jeden z powodów, dlaczego jest najlepszym sposobem na ich realizację jest poprzez wyliczenia:

public enum YourSingleton { 
    INSTANCE; 
    // methods go here 
} 

Jeśli mówimy o użyciu setAccessible() ogólnie: jeśli kod jest napisane przez kogoś, komu nie ufasz, że nie będziesz robić takich sztuczek, nie powinieneś go uruchamiać (lub uruchamiać go w piaskownicy). Wśród programistów, publiczna/prywatna powinna być uważana za metainformację o tym, w jaki sposób kod ma być używany - nie jako funkcja bezpieczeństwa.

0

AFAIK jest to rodzaj metaprogramowania i dlatego wymaga sprawdzenia innej warstwy abstrakcji. Z Javadoc, przypuszczam, powinieneś użyć SecurityManager, aby wymusić pożądane zachowanie: setAccessible(). Generalnie IMHO powinieneś naprawdę wiedzieć, co robisz, gdy jesteś metaprogramming i zmiana dostępu powinna naprawdę mieć dobre powody do zrobienia.

0

Możesz zrobić tak.

private static final Private INSTANCE = new Private(); 
    private Private() { 
     if(INSTANCE !=null) 
      throw new IllegalStateException("Already instantiated"); 
    } 
    public static Private getInstance() { 
      return INSTANCE; 
     } 
+0

Singleton jest poza jego zasięgiem w słoiku strony trzeciej. To w ogóle nie pomoże. Ta technika nie jest bezpieczna, ponieważ możesz ją zmienić poprzez odbicie (jak wspomniano w pytaniu). – whiskeysierra