Czym jest refleksja i dlaczego jest przydatna?

Czym jest refleksja i dlaczego jest przydatna?

Szczególnie interesuje mnie Java, ale zakładam, że zasady są takie same w każdym języku.

Author: laike9m, 2008-09-01

22 answers

Nazwa reflection jest używana do opisu kodu, który jest w stanie sprawdzić inny kod w tym samym systemie (lub samym sobie).

Na przykład, powiedzmy, że masz obiekt nieznanego typu w Javie i chcesz wywołać na nim metodę 'doSomething', jeśli taka istnieje. STATYCZNY system pisania w Javie nie jest tak naprawdę zaprojektowany, aby to obsługiwać, chyba że obiekt jest zgodny ze znanym interfejsem, ale używając reflection, Twój kod może spojrzeć na obiekt i dowiedzieć się, czy ma metodę o nazwie "doSomething", a następnie zadzwoń, jeśli chcesz.

Więc, aby dać ci przykład kodu w Javie (wyobraź sobie, że przedmiot, o którym mowa, to foo):

Method method = foo.getClass().getMethod("doSomething", null);
method.invoke(foo, null);

Bardzo powszechnym przypadkiem użycia w Javie jest użycie z adnotacjami. Na przykład JUnit 4 użyje reflection, aby przejrzeć klasy w poszukiwaniu metod oznaczonych adnotacją @Test, a następnie wywoła je podczas uruchamiania testu jednostkowego.

Jest kilka dobrych przykładów refleksji na początek http://docs.oracle.com/javase/tutorial/reflect/index.html

I wreszcie, tak, pojęcia są bardzo podobne w innych statycznie typowanych językach, które wspierają refleksję (jak C#). W językach typowanych dynamicznie, opisany powyżej przypadek użycia jest mniej konieczny (ponieważ kompilator pozwoli na wywołanie dowolnej metody na dowolnym obiekcie, co w trybie runtime się nie powiedzie, jeśli nie istnieje), ale drugi przypadek szukania metod, które są oznaczone lub działają w określony sposób jest nadal pospolite.

Aktualizacja z komentarza:

Możliwość sprawdzania kodu w systemie i przeglądania typów obiektów jest Nie odbicie, ale raczej Typ introspekcji. Refleksja jest wtedy możliwość wprowadzania zmian w czasie wykonywania poprzez wykorzystanie introspekcja. Rozróżnienie jest tutaj konieczne, ponieważ niektóre języki wspieraj introspekcję, ale nie wspieraj refleksji. Jeden z takich przykładów is C++

 1792
Author: Matt Sheppard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-07 23:08:52

Reflection to zdolność języka do sprawdzania i dynamicznego wywoływania klas, metod, atrybutów itp. w czasie wykonywania.

Na przykład, wszystkie obiekty w Javie posiadają metodę getClass(), która pozwala określić klasę obiektu, nawet jeśli nie znasz jej w czasie kompilacji (np. jeśli zadeklarowałeś ją jako Object) - może to wydawać się trywialne, ale takie odbicie nie jest możliwe w mniej dynamicznych językach, takich jak C++. Bardziej zaawansowane zastosowania pozwalają na wyświetlanie i wywoływanie metod, konstruktorów itp.

Refleksja jest ważna, ponieważ pozwala pisać programy, które nie muszą "wiedzieć" wszystkiego w czasie kompilacji, czyniąc je bardziej dynamicznymi, ponieważ mogą być ze sobą powiązane w czasie wykonywania. Kod może być napisany na podstawie znanych interfejsów, ale rzeczywiste klasy, które mają być użyte, mogą być utworzone za pomocą odbicia z plików konfiguracyjnych.

Wiele nowoczesnych frameworków wykorzystuje szeroko refleksję właśnie z tego powodu. Większość innych współczesnych języków używa również refleksji, a w językach skryptowych (takich jak Python) są one jeszcze bardziej zintegrowane, ponieważ wydaje się to bardziej naturalne w ogólnym modelu programowania tych języków.

 266
Author: Liedman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-24 00:36:55

Jednym z moich ulubionych zastosowań reflection jest poniższa metoda zrzutu Javy. Przyjmuje dowolny obiekt jako parametr i używa Java reflection API do wydruku każdej nazwy pola i wartości.

import java.lang.reflect.Array;
import java.lang.reflect.Field;

public static String dump(Object o, int callCount) {
    callCount++;
    StringBuffer tabs = new StringBuffer();
    for (int k = 0; k < callCount; k++) {
        tabs.append("\t");
    }
    StringBuffer buffer = new StringBuffer();
    Class oClass = o.getClass();
    if (oClass.isArray()) {
        buffer.append("\n");
        buffer.append(tabs.toString());
        buffer.append("[");
        for (int i = 0; i < Array.getLength(o); i++) {
            if (i < 0)
                buffer.append(",");
            Object value = Array.get(o, i);
            if (value.getClass().isPrimitive() ||
                    value.getClass() == java.lang.Long.class ||
                    value.getClass() == java.lang.String.class ||
                    value.getClass() == java.lang.Integer.class ||
                    value.getClass() == java.lang.Boolean.class
                    ) {
                buffer.append(value);
            } else {
                buffer.append(dump(value, callCount));
            }
        }
        buffer.append(tabs.toString());
        buffer.append("]\n");
    } else {
        buffer.append("\n");
        buffer.append(tabs.toString());
        buffer.append("{\n");
        while (oClass != null) {
            Field[] fields = oClass.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                buffer.append(tabs.toString());
                fields[i].setAccessible(true);
                buffer.append(fields[i].getName());
                buffer.append("=");
                try {
                    Object value = fields[i].get(o);
                    if (value != null) {
                        if (value.getClass().isPrimitive() ||
                                value.getClass() == java.lang.Long.class ||
                                value.getClass() == java.lang.String.class ||
                                value.getClass() == java.lang.Integer.class ||
                                value.getClass() == java.lang.Boolean.class
                                ) {
                            buffer.append(value);
                        } else {
                            buffer.append(dump(value, callCount));
                        }
                    }
                } catch (IllegalAccessException e) {
                    buffer.append(e.getMessage());
                }
                buffer.append("\n");
            }
            oClass = oClass.getSuperclass();
        }
        buffer.append(tabs.toString());
        buffer.append("}\n");
    }
    return buffer.toString();
}
 121
Author: Ben Williams,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-29 00:08:22

Zastosowania refleksji

Reflection jest powszechnie używany przez programy, które wymagają możliwości zbadania lub modyfikacji zachowania uruchomieniowego aplikacji uruchomionych w maszynie wirtualnej Java. Jest to stosunkowo zaawansowana funkcja i powinna być używana tylko przez programistów, którzy mają silne zrozumienie podstaw języka. Mając to na uwadze, odbicie jest potężną techniką i może umożliwić aplikacjom wykonywanie operacji, które w przeciwnym razie byłyby niemożliwe.

Funkcje Rozszerzalności

Aplikacja może korzystać z zewnętrznych, zdefiniowanych przez użytkownika klas, tworząc instancje obiektów rozszerzalności przy użyciu ich w pełni kwalifikowanych nazw. Klasy przeglądarek i środowisk rozwoju wizualnego Przeglądarka klas musi być w stanie wyliczyć członków klas. Wizualne Środowiska programistyczne mogą skorzystać z wykorzystania informacji o typach dostępnych w reflection, aby pomóc programistom w pisaniu poprawnego kodu. Debuggery i Narzędzia Testowe Debuggery muszą mieć możliwość sprawdzania prywatnych członków w klasach. Wiązki testowe mogą wykorzystywać refleksję do systematycznego wywoływania wykrywalnych zestawów API zdefiniowanych NA klasie, aby zapewnić wysoki poziom pokrycia kodu w zestawie testowym.

Wady odbicia

Odbicie jest potężne, ale nie powinno być używane masowo. Jeśli możliwe jest wykonanie operacji bez użycia odbicia, lepiej jest unikać jej używania. Następujące kwestie dotyczą należy pamiętać o dostępie do kodu poprzez odbicie.

  • Wydajność Napowietrzna

Ponieważ reflection obejmuje typy, które są rozwiązywane dynamicznie, pewne optymalizacje maszyn wirtualnych Java nie mogą być wykonywane. W związku z tym operacje odblaskowe mają wolniejszą wydajność niż ich nieodblaskowe odpowiedniki i należy ich unikać w sekcjach kodu, które są często nazywane w aplikacjach wrażliwych na wydajność.

  • bezpieczeństwo Ograniczenia

Reflection wymaga uprawnień runtime, które mogą nie być obecne podczas uruchamiania pod menedżerem zabezpieczeń. Jest to ważne w przypadku kodu, który musi działać w ograniczonym kontekście bezpieczeństwa, takim jak aplet.

  • ekspozycja wewnętrznych

Ponieważ reflection pozwala kodowi na wykonywanie operacji, które byłyby nielegalne w kodzie nieodblaskowym, takich jak dostęp do prywatnych pól i metod, użycie reflection może skutkować nieoczekiwanymi efektami ubocznymi, które mogą sprawić, że kod będzie dysfunkcyjny i zniszczy przenośność. Kod odblaskowy łamie abstrakcje i dlatego może zmieniać zachowanie wraz z aktualizacjami platformy.

Source: the Reflection API

 89
Author: Desmond Smith,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-24 17:20:41

Reflection jest kluczowym mechanizmem pozwalającym aplikacji lub frameworkowi na pracę z kodem, który mógł jeszcze nie zostać napisany!

Weźmy na przykład typową sieć.plik xml. Będzie to zawierać listę elementów servlet, które zawierają zagnieżdżone elementy klasy servlet. Kontener servlet przetworzy sieć.pliku xml, i utwórz nową instancję każdej klasy servlet poprzez reflection.

Innym przykładem może być Java API for XML Parsing (JAXP) . Gdzie Dostawca parserów XML jest "podłączany" przez dobrze znane właściwości systemu, które są używane do konstruowania nowych instancji poprzez odbicie.

I wreszcie, najbardziej wszechstronnym przykładem jest Spring , która wykorzystuje odbicie do tworzenia swoich fasoli, a do intensywnego stosowania proxy

 47
Author: toolkit,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-01 09:30:55

Nie każdy język wspiera refleksję, ale zasady są zwykle takie same w językach, które ją wspierają.

Refleksja to zdolność do "refleksji" nad strukturą programu. Albo bardziej konkretny. Aby spojrzeć na obiekty i klasy, które posiadasz i programowo uzyskać informacje o metodach, polach i interfejsach, które implementują. Możesz również spojrzeć na rzeczy, takie jak adnotacje.

Przydaje się w wielu sytuacjach. Wszędzie, gdzie chcesz być w stanie dynamicznie podłącz klasy do kodu. Wiele maperów relacyjnych obiektów korzysta z funkcji reflection, aby tworzyć instancje obiektów z baz danych, nie wiedząc z góry, jakich obiektów będą używać. Architektura wtyczek to kolejne miejsce, w którym przydaje się odbicie. Możliwość dynamicznego ładowania kodu i określenia, czy istnieją typy, które implementują odpowiedni interfejs do użycia jako wtyczka, jest ważna w takich sytuacjach.

 39
Author: Mendelt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-10-09 03:53:34

Reflection pozwala na tworzenie instancji nowych obiektów, wywoływanie metod i uzyskiwanie/ustawianie operacji na zmiennych klasy dynamicznie w czasie wykonywania bez uprzedniej wiedzy o jej implementacji.

Class myObjectClass = MyObject.class;
Method[] method = myObjectClass.getMethods();

//Here the method takes a string parameter if there is no param, put null.
Method method = aClass.getMethod("method_name", String.class); 

Object returnValue = method.invoke(null, "parameter-value1");

W powyższym przykładzie parametr null jest obiektem, do którego ma zostać wywołana metoda. Jeśli metoda jest statyczna, podajesz null. Jeżeli metoda nie jest statyczna, wtedy podczas wywoływania należy podać poprawną instancję MyObject zamiast null.

Refleksja pozwala również na access private member / methods of a class:

public class A{

  private String str= null;

  public A(String str) {
  this.str= str;
  }
}

.

A obj= new A("Some value");

Field privateStringField = A.class.getDeclaredField("privateString");

//Turn off access check for this field
privateStringField.setAccessible(true);

String fieldValue = (String) privateStringField.get(obj);
System.out.println("fieldValue = " + fieldValue);
  • do kontroli klas (znanej również jako introspekcja) nie trzeba importować pakietu reflection (java.lang.reflect). Metadane klasy można uzyskać poprzez java.lang.Class.

Reflection jest bardzo potężnym API, ale może spowolnić aplikację, jeśli jest używana w nadmiarze, ponieważ rozwiązuje wszystkie typy w czasie wykonywania.

 35
Author: Nikhil Shekhar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-08 18:25:33

Java Reflection jest dość potężna i może być bardzo przydatna. Java Reflection umożliwia sprawdzanie klas, interfejsów, pól i metod w czasie wykonywania, bez znajomości nazw klas, metod itp. w czasie kompilacji. Możliwe jest również Tworzenie instancji nowych obiektów, wywoływanie metod i uzyskiwanie / ustawianie wartości pól za pomocą odbicia.

Szybki przykład Java Reflection, aby pokazać, jak wygląda używanie reflection:

Method[] methods = MyObject.class.getMethods();

    for(Method method : methods){
        System.out.println("method = " + method.getName());
    }

Ten przykład otrzymuje obiekt klasy z klasy o nazwie MyObject. Przy pomocy obiektu class przykład pobiera listę metod w danej klasie, iterację metod i wypisuje ich nazwy.

Dokładnie jak to wszystko działa jest wyjaśnione tutaj

Edit: po prawie 1 roku edytuję tę odpowiedź, ponieważ czytając o refleksji mam jeszcze kilka zastosowań refleksji.

  • Wiosna wykorzystuje konfigurację fasoli, taką jak:


<bean id="someID" class="com.example.Foo">
    <property name="someField" value="someValue" />
</bean>

Gdy Spring context przetwarza ten element , użyje klasy.forName (String) z argumentem " com.przykład.Foo", aby utworzyć tę klasę.

Następnie ponownie użyje reflection, aby uzyskać odpowiedni setter dla elementu i ustawić jego wartość na określoną wartość.

    Junit używa Reflection szczególnie do testowania prywatnych / chronionych metod.

Dla metod prywatnych,

Method method = targetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);

Dla pól prywatnych,

Field field = targetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);
 24
Author: Vedant Kekan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-26 06:38:04

Przykład:

Weźmy na przykład zdalną aplikację, która daje aplikacji obiekt, który można uzyskać za pomocą ich metod API . Teraz na podstawie obiektu może być konieczne wykonanie pewnego rodzaju obliczeń .

Dostawca gwarantuje, że obiekt może być 3 typów i musimy wykonać obliczenia na podstawie jakiego typu obiektu .

Możemy więc zaimplementować w 3 klasach, z których każda zawiera inną logikę .Oczywiście informacje o obiekcie są dostępne w runtime, więc nie możesz statycznie kodować do wykonywania obliczeń, dlatego reflection jest używane do tworzenia instancji obiektu klasy wymaganej do wykonania obliczeń w oparciu o obiekt otrzymany od dostawcy .

 21
Author: human.js,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-14 14:55:43

Reflection {[8] } jest API, które służy do sprawdzania lub modyfikowania zachowania metod, klas, interfejsów w czasie wykonywania.

  1. wymagane klasy do refleksji są podane w java.lang.reflect package.
  2. Reflection daje nam informacje o klasie, do której należy obiekt, a także o metodach tej klasy, które można wykonać za pomocą tego obiektu.
  3. poprzez reflection możemy wywoływać metody w trybie runtime niezależnie od użytego identyfikatora dostępu z nimi.

Pakiety java.lang i java.lang.reflect zapewniają klasy dla Java reflection.

Reflection może być użyte do uzyskania informacji o –

  1. Class Metoda getClass() jest używana do uzyskania nazwy klasy, do której należy obiekt.

  2. Konstruktory metoda getConstructors() jest używana do uzyskania publicznych konstruktorów klasy, do której należy obiekt.

  3. Metody metoda getMethods() jest stosowana aby uzyskać publiczne metody klasy, do której należy obiekt.

The Reflection API jest używany głównie w:

IDE (Integrated Development Environment) np. Eclipse, MyEclipse, NetBeans itp.
Debugger i narzędzia testowe itp.

Zalety używania odbicia:

Funkcje rozszerzalności: Aplikacja może korzystać z zewnętrznych, zdefiniowanych przez użytkownika klas, tworząc instancje obiekty rozszerzalności przy użyciu ich w pełni kwalifikowanych nazw.

narzędzia do debugowania i testowania: Debugery używają właściwości reflection do sprawdzania prywatnych członków klas.

Wady:

narzut wydajności: operacje odblaskowe mają wolniejszą wydajność niż ich nieodblaskowe odpowiedniki i należy ich unikać w sekcjach kodu, które są często wywoływane w aplikacjach wrażliwych na wydajność.

ekspozycja na Wewnętrzne: Odblaskowy kod łamie abstrakcje i dlatego może zmieniać zachowanie wraz z aktualizacjami platformy.

Ref: Java Reflection javarevisited.blogspot.in

 19
Author: roottraveller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-22 07:27:08

Prosty przykład refleksji. W grze w szachy nie wiesz, co zostanie przeniesione przez użytkownika w czasie wykonywania. reflection może być użyte do wywołania metod, które są już zaimplementowane w czasie wykonywania:

public class Test {

    public void firstMoveChoice(){
        System.out.println("First Move");
    } 
    public void secondMOveChoice(){
        System.out.println("Second Move");
    }
    public void thirdMoveChoice(){
        System.out.println("Third Move");
    }

    public static void main(String[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { 
        Test test = new Test();
        Method[] method = test.getClass().getMethods();
        //firstMoveChoice
        method[0].invoke(test, null);
        //secondMoveChoice
        method[1].invoke(test, null);
        //thirdMoveChoice
        method[2].invoke(test, null);
    }

}
 19
Author: Isuru Jayakantha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-14 14:56:25

Zgodnie z moim zrozumieniem:

Reflection pozwala programiście na dynamiczny dostęp do elementów w programie. tzn. podczas kodowania aplikacji, jeśli programista nie jest świadomy klasy lub jej metod, może korzystać z takiej klasy dynamicznie (w czasie wykonywania) za pomocą reflection.

Jest często używany w scenariuszach, w których nazwa klasy często się zmienia. W przypadku wystąpienia takiej sytuacji programista skomplikuje przepisanie aplikacji i zmianę nazwy klasy znowu i znowu.

Zamiast tego, używając reflection, trzeba się martwić o ewentualną zmianę nazwy klasy.

 17
Author: pramod,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-02 16:30:06

Reflection to zestaw funkcji, który pozwala na dostęp do informacji o uruchomieniu programu i modyfikowanie jego zachowania (z pewnymi ograniczeniami).

Jest to przydatne, ponieważ pozwala zmienić zachowanie runtime w zależności od meta informacji programu, to znaczy można sprawdzić typ zwracanej funkcji i zmienić sposób radzenia sobie z sytuacją.

W C# na przykład można załadować assembly (a .dll) w trybie runtime, poruszając się po zajęcia i podejmowanie działań zgodnie z tym, co znalazłeś. Pozwala również utworzyć instancję klasy w trybie runtime, wywołać jej metodę, itd.

Gdzie może się przydać? Nie jest przydatny za każdym razem, ale w konkretnych sytuacjach. Na przykład możesz go użyć, aby uzyskać nazwę klasy do celów logowania, aby dynamicznie tworzyć procedury obsługi zdarzeń zgodnie z tym, co jest określone w pliku konfiguracyjnym i tak dalej...

 15
Author: Jorge Córdoba,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-03-27 20:37:23

Chcę tylko dodać jakiś punkt do wszystkiego, co było wymienione.

Za pomocą Reflection API można napisać uniwersalną metodę toString() dla dowolnego obiektu.

Jest przydatny przy debugowaniu.

Oto przykład:

class ObjectAnalyzer {

   private ArrayList<Object> visited = new ArrayList<Object>();

   /**
    * Converts an object to a string representation that lists all fields.
    * @param obj an object
    * @return a string with the object's class name and all field names and
    * values
    */
   public String toString(Object obj) {
      if (obj == null) return "null";
      if (visited.contains(obj)) return "...";
      visited.add(obj);
      Class cl = obj.getClass();
      if (cl == String.class) return (String) obj;
      if (cl.isArray()) {
         String r = cl.getComponentType() + "[]{";
         for (int i = 0; i < Array.getLength(obj); i++) {
            if (i > 0) r += ",";
            Object val = Array.get(obj, i);
            if (cl.getComponentType().isPrimitive()) r += val;
            else r += toString(val);
         }
         return r + "}";
      }

      String r = cl.getName();
      // inspect the fields of this class and all superclasses
      do {
         r += "[";
         Field[] fields = cl.getDeclaredFields();
         AccessibleObject.setAccessible(fields, true);
         // get the names and values of all fields
         for (Field f : fields) {
            if (!Modifier.isStatic(f.getModifiers())) {
               if (!r.endsWith("[")) r += ",";
               r += f.getName() + "=";
               try {
                  Class t = f.getType();
                  Object val = f.get(obj);
                  if (t.isPrimitive()) r += val;
                  else r += toString(val);
               } catch (Exception e) {
                  e.printStackTrace();
               }
            }
         }
         r += "]";
         cl = cl.getSuperclass();
      } while (cl != null);

      return r;
   }    
}
 12
Author: catch23,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-20 22:22:03

Odbicie to pozwolić obiektowi zobaczyć ich wygląd. Ten argument nie ma nic wspólnego z refleksją. W rzeczywistości jest to zdolność "samoidentyfikacji".

Reflection samo w sobie jest wyrazem dla takich języków, które nie posiadają zdolności samowiedzy i samowystarczalności jak Java i C#. Ponieważ nie mają one zdolności samowiedzy, kiedy chcemy obserwować, jak to wygląda, musimy mieć inną rzecz, aby zastanowić się nad tym, jak to wygląda. Doskonałych języków dynamicznych, takich jak Ruby i Python może postrzegać odbicie własnego bez pomocy innych osób. Można powiedzieć, że obiekt Javy nie może postrzegać tego, jak wygląda bez lustra, które jest obiektem klasy reflection, ale obiekt w Pythonie może postrzegać go bez lustra. Dlatego potrzebujemy odbicia w Javie.

 11
Author: Marcus Thornton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-24 17:22:16

Z dokumentacji Javy Strona

java.lang.reflect pakiet zawiera klasy i interfejsy do uzyskiwania informacji odblaskowych o klasach i obiektach. Reflection umożliwia programowy dostęp do informacji o polach, metodach i konstruktorach załadowanych klas oraz wykorzystanie odbitych pól, metod i konstruktorów do działania na ich podstawowych odpowiednikach, w ramach ograniczeń bezpieczeństwa.

AccessibleObject umożliwia zablokowanie kontroli dostępu, jeżeli konieczne {[2] } jest dostępne.

Klasy w tym pakiecie, wraz z java.lang.Class zawierają aplikacje, takie jak debuggery, Interpretatory, inspektory obiektów, przeglądarki klas i usługi, takie jak Object Serialization i JavaBeans, które potrzebują dostępu do publicznych elementów obiektu docelowego (na podstawie jego klasy runtime) lub elementów zadeklarowanych przez daną klasę

Zawiera następujące funkcje.

  1. uzyskanie obiektów klasy,
  2. sprawdzanie właściwości klasy (pól, metody, konstruktory),
  3. Ustawianie i pobieranie wartości pól,
  4. metody wywoływania,
  5. tworzenie nowych instancji obiektów.

Spójrz na to dokumentacja link do metod narażonych przez Class klasy.

Z tego

Artykułu (autorstwa Dennisa Sosnoskiego, Prezesa, Sosnoski Software Solutions, Inc) i tego artykułu (security-explorations pdf):

Widzę znaczne wady niż zastosowania of using Reflection

User of Reflection:

  1. zapewnia bardzo wszechstronny sposób dynamicznego łączenia komponentów programu
  2. jest to przydatne do tworzenia bibliotek, które działają z obiektami w bardzo ogólny sposób

wady odbicia:

  1. odbicie jest znacznie wolniejsze niż kod bezpośredni, gdy jest używane do dostępu do pól i metod.
  2. może zaciemnić to, co dzieje się w Twoim kod
  3. to omija kod źródłowy może powodować problemy z konserwacją
  4. Kod odbicia jest również bardziej złożony niż odpowiadający mu kod bezpośredni
  5. pozwala naruszać kluczowe ograniczenia bezpieczeństwa Javy, takie jako ochrona dostępu do danych i bezpieczeństwo typu

ogólne nadużycia:

  1. wczytywanie klas ograniczonych,
  2. uzyskiwanie odniesień do konstruktorów, metod lub pól klasy zamkniętej,
  3. Tworzenie nowe instancje obiektów, wywoływanie metod, pobieranie lub ustawianie wartości pól klasy zastrzeżonej.

Spójrz na to pytanie SE dotyczące nadużywania funkcji refleksji:

Jak odczytać prywatne pole w Javie?

Podsumowanie:

brak bezpieczeństwa korzystania z jego funkcji prowadzonych z poziomu kodu systemowego może również łatwo prowadzić do kompromisu w trybie bezpieczeństwa Java {38]}l. więc korzystaj z tej funkcji oszczędnie

 9
Author: Ravindra babu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:34:53

Jak sama nazwa wskazuje odzwierciedla to, co przechowuje na przykład metodę klasy, itd. poza dostarczeniem funkcji do wywołania metody tworzącej instancję dynamicznie w trybie runtime.

Jest używany przez wiele frameworków i aplikacji pod wood do wywoływania usług bez znajomości kodu.

 9
Author: Mohammed Sarfaraz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-09 02:29:34

Reflection daje możliwość pisania bardziej ogólnego kodu. Pozwala na tworzenie obiektu w trybie runtime i wywołanie jego metody w trybie runtime. Stąd program może być wysoce sparametryzowany. Pozwala również introspekcji obiektu i klasy do wykrywania jego zmiennych i metody narażone na świat zewnętrzny.

 7
Author: saumik gupta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-24 17:22:09

Reflection posiada wiele zastosowań . Tym, z którym jestem bardziej zaznajomiony, jest możliwość tworzenia kodu w locie.

IE: klasy dynamiczne, funkcje, konstruktory-na podstawie dowolnych danych (XML/array / SQL results / hardcoded / etc..)

 6
Author: Ess Kay,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-23 05:47:19

Chcę odpowiedzieć na to pytanie przez przykład. Przede wszystkim projekt Hibernate używa Reflection API do generowania instrukcji CRUD, aby pomostować przepaść między uruchomioną aplikacją a magazynem trwałości. Gdy rzeczy zmieniają się w domenie, Hibernate MUSI o nich wiedzieć, aby zapisać je do magazynu danych i odwrotnie.

Alternatywnie działa Lombok Project. Po prostu wstrzykuje kod w czasie kompilacji, co powoduje, że kod jest wstawiany do klas domeny. (Myślę, że jest OK dla getterów i setters)

Hibernate Wybierz reflection, ponieważ ma minimalny wpływ na proces budowania aplikacji.

I z Javy 7 mamy MethodHandles, który działa jako Reflection API. W projektach do pracy z loggerami wystarczy skopiować i wkleić następny kod:

Logger LOGGER = Logger.getLogger(MethodHandles.lookup().lookupClass().getName());

Ponieważ w tym przypadku trudno jest popełnić błąd literówki.

 3
Author: BSeitkazin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-12-05 06:35:57

Ponieważ uważam, że najlepiej jest wyjaśnić przykładem i żadna z odpowiedzi nie wydaje się tego robić...

Praktycznym przykładem użycia reflections byłby Serwer języka Java napisany w Javie lub serwer języka PHP napisany w PHP itp. Serwer językowy daje możliwości IDE, takie jak autouzupełnianie, skok do definicji, pomoc kontekstowa, typy podpowiedzi i wiele innych. Aby wszystkie nazwy znaczników (słowa, które można autouzupełniać) pokazywały wszystkie możliwe dopasowania podczas wpisywania, Serwer językowy musi sprawdzić wszystko o klasie włącznie z blokami doc i prywatnymi członkami. Do tego potrzebne jest odzwierciedlenie tej klasy.

Innym przykładem może być test jednostkowy metody prywatnej. Jednym ze sposobów jest stworzenie refleksji i zmiana zakresu metody na publiczny w fazie konfiguracji testu. Oczywiście można twierdzić, że prywatne metody nie powinny być testowane bezpośrednio, ale nie o to chodzi.

 3
Author: cprn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-24 12:51:51

Ważne

Począwszy od Javy 9 nie można dłużej używać reflection, chyba że pakiet-info.java otwiera moduł dostępu do odbicia.

Domyślnie dostęp do wszystkich pakietów w module jest zabroniony.

Zobacz Zrozumienie Modułów Java 9

 0
Author: RSG,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-23 23:01:52