• Artykuły
  • Forum
  • Ciekawostki
  • Encyklopedia
  • Mechanizm refleksji

    Przeczytaj także...
    Język wysokiego poziomu (autokod) – typ języka programowania, którego składnia i słowa kluczowe mają maksymalnie ułatwić rozumienie kodu programu dla człowieka, tym samym zwiększając poziom abstrakcji i dystansując się od sprzętowych niuansów. Kod napisany w języku wysokiego poziomu nie jest bezpośrednio „zrozumiały” dla komputera – większość kodu stanowią tak naprawdę normalne słowa, np. w języku angielskim. Aby umożliwić wykonanie programu napisanego w tym języku należy dokonać procesu kompilacji.C# (C Sharp, dosłownie "C-krzyżyk", "cis") – obiektowy język programowania zaprojektowany przez zespół pod kierunkiem Andersa Hejlsberga dla firmy Microsoft.
    Ruby to interpretowany, w pełni obiektowy i dynamicznie typowany język programowania stworzony w 1995 roku przez Yukihiro Matsumoto (pseudonim Matz). W języku angielskim ruby oznacza rubin.

    Mechanizm refleksji – pojęcie z dziedziny informatyki oznaczające proces, dzięki któremu program komputerowy może być modyfikowany w trakcie działania w sposób zależny od własnego kodu oraz od zachowania w trakcie wykonania. Paradygmat programowania ściśle związany z mechanizmem refleksji to programowanie refleksyjne.

    Objective-C – rozszerzenie języka C o możliwości obiektowe, wzorowane na Smalltalku. Objective-C przyjął drogę całkowicie odmienną od C++. Jest używany głównie w frameworku Cocoa w systemie Mac OS X oraz w iOS.Paradygmat programowania (ang. programming paradigm) — wzorzec programowania komputerów przedkładany w danym okresie rozwoju informatyki ponad inne lub szczególnie ceniony w pewnych okolicznościach lub zastosowaniach.

    Refleksja pozwala w łatwy sposób zarządzać kodem tak, jakby był danymi. Używa się jej najczęściej do zmieniania standardowego zachowania już zdefiniowanych metod lub funkcji, a także do tworzenia własnych konstrukcji semantycznych modyfikujących język. Z drugiej strony kod wykorzystujący refleksję jest mniej czytelny i nie pozwala na sprawdzenie poprawności składniowej i semantycznej w trakcie kompilacji (niewygodne śledzenie błędów).

    GitHub – hostingowy serwis internetowy przeznaczony dla projektów programistycznych wykorzystujących system kontroli wersji Git. Stworzony został przy wykorzystaniu języków Ruby on Rails i Erlang. Serwis ruszył w kwietniu 2008 roku. W kwietniu 2011 ogłoszono, iż GitHub obsługuje 2 miliony repozytoriów.Definicja intuicyjna: Java (wym. „dżawa”) to język programowania. Programy napisane w Javie można uruchamiać na wielu urządzeniach, takich jak telefony komórkowe lub komputery oraz pod różnymi systemami operacyjnymi, przy użyciu Wirtualnej maszyny Javy, która musi być w danym środowisku zainstalowana.

    Mechanizm ten jest częściej spotykany w językach wysokiego poziomu, zwykle opartych na maszynie wirtualnej.

    Przykłady[]

    C#[]

    Poniższy przykład demonstruje użycie refleksji w języku C Sharp używając pakietu System.Reflection

    //bez refleksji
    Foo foo = new Foo();
    foo.hello();
    
    //z użyciem refleksji
    var type = Type.GetType("namespace.foo");   //string powinien zawierać namespace naszej klasy
    var foo = Activator.CreateInstance(type); //inicjalizacja obiektu określonego typu
    MethodInfo inf = t.GetMethod("hello"); 
    inf.Invoke(foo); // jako drugi parametr metoda Invoke przyjmuje tablicę Object są to parametry metody hello.
    

    Objective-C[]

    Poniższy przykład demonstruje użycie refleksji w języku Objective-C

    // bez refleksji
    Foo *foo = [[Foo alloc] init];
    [foo hello];
    [foo release];
    
    // z refleksją
    id foo = [[NSClassFromString(@"Foo") alloc] init];
    SEL selector = NSSelectorFromString(@"hello");
    [foo performSelector:selector];
    [foo release];
    

    Java[]

    Poniższy przykład w języku Java wykorzystuje pakiet java.lang.reflect.

     // bez refleksji
     Foo foo = new Foo();
     foo.hello();
    
     // z refleksją
     Class cl = Class.forName("Foo");
     Method method = cl.getMethod("hello");
     method.invoke(cl.newInstance());
    

    Oba fragmenty tworzą instancję klasy Foo, następnie wywołują metodę hello() tej klasy. Różnica polega na tym, że w pierwszym fragmencie nazwa klasy i metody są częścią kodu źródłowego, podczas gdy w drugim fragmencie możliwe jest przeniesienie ich do zmiennych, których wartość jest ustalana w czasie wykonania kodu.

    Mechanizm refleksji pozwala także na zdobywanie informacji o klasach w trakcie wykonania programu. W poniższym przykładzie Klasa Main sprawdza jaki jest typ zwracany przez metody klasy Bar.

    public class Bar {
        public String fun(Integer i) {
            return "0" + i + ", zglos sie!";
        }
    }
    
    import static java.lang.System.out;
    import java.lang.reflect.*;
    
    public class Main {
        public static void main(String args) throws Exception {
            String className = "Bar";
            Class c = Class.forName(className);
            Method m = c.getDeclaredMethods();
            for (int i=0;i<m.length;++i) {
    	    out.print("Klasa " + className + " ma metode '" + m[i].getName().toString() + "'");
    	    out.println(" ktora zwraca wartosc typu " + m[i].getReturnType().toString());
            }
        }
    }
    

    Ruby[]

    Przykład w języku Ruby, który dodaje metodę klasową once, pozwalającą zaznaczyć, że dana funkcja składowa klasy ma być wykonywana tylko raz. Podprogram modyfikuje kod oznaczonych metod w taki sposób, że nadaje im nową nazwę. Pod starą nazwą umieszcza nową metodę, która buforuje wartość zwracaną przez pierwotnie zdefiniowaną funkcję, tym samym pozwalając się jej wykonać tylko raz.

    # part of date.rb - date and time library
    # Author: Tadayoshi Funaba 1998-2008
    
    class Date
     class << self
    
        def once(*ids) # :nodoc: -- restricted
          for id in ids
            module_eval <<-"end;"
              alias_method :__#{id.object_id}__, :#{id.to_s}
              private :__#{id.object_id}__
              def #{id.to_s}(*args)
                @__ca__[#{id.object_id}] ||= __#{id.object_id}__(*args)
              end
            end;
          end
        end
    
        private :once
    
      end
    end
    

    Inny przykład to rozszerzenie możliwości języka o konstrukcję automatycznie kasującą zawartość wskazanych przez programistę buforów, jeśli uruchomione zostaną wyszczególnione metody. Zadaniem metaprogramu jest tu również opakowanie metod, jednak zapamiętywane są identyfikatory ich obiektów a nie identyfikatory obiektów ich symbolicznych nazw. Metaprogram zawarto w przykładowym module BufferAffects, który można pobrać z serwisu GitHub. Domieszkując ten moduł możemy korzystać z dodatkowych metod klasowych pozwalających na stosowanie w kodzie klauzul buffers_reset_method i attr_affects_buffers:

    require 'bufferaffects'  # http://gist.github.com/88178
    
    class Main
    
      # domieszkowanie modułu
      extend BufferAffects
    
      # metoda opróżniająca wykorzystywany bufor
      buffers_reset_method :reset_path_buffer
    
      # pola które po zmianie powinny wpływać na
      # zawartość bufora
      attr_affects_buffers :subpart
    
      # standardowe akcesory pól
      attr_accessor        :subpart, :otherpart
    
      # metoda opróżniająca bufor
      def reset_path_buffer(name)
        @path = nil
        p "uruchomiono reset dla #{name}"
      end
    
      # metoda z buforowanym wyjściem
      def path
        @path ||= @subpart.to_s + @otherpart.to_s
      end
    
    end
    
    # tworzenie nowego obiektu
    obj = Main.new
    
    # ustawianie jednego z pól
    # i wyświetlanie buforowanych wynikow
    obj.subpart = 'test'
    p obj.path
    obj.subpart = '1234'
    p obj.path
    

    Linki zewnętrzne[]

  • Java. Obiekty refleksyjne – artykuł wyjaśniający co to są refleksje i jak się je stosuje w Javie



  • w oparciu o Wikipedię (licencja GFDL, CC-BY-SA 3.0, autorzy, historia, edycja)

    Reklama

    Czas generowania strony: 0.022 sek.