Commit 3c6a4a97 by Patryk Czarnik

Przykłady refleksji

parent bf3ef82b
- p01_interakcja
- argumenty
- konsola
- okna
- p02_zmienne
- p03_instrukcje
- a_if
- b_petle
- c_switch
- p04_operatory
- p05_liczby
- p06_funkcje
- gdyby_nie_bylo_static
- importowanie
- przyklady
- teoria
- p10_klasy_podstawy
- p11_referencje
- p12_dziedziczenie
- a_podstawy
- konstruktory_z_nadklasy
- nadpisywanie
- nadpisywanie_i_przeslanianie
- przeslanianie
- superthis
- p13_abstrakcyjne
- p14_interfejsy
- p15_inicjalizacja
- p16_widocznosc
- inny_pakiet
- p17_przeslanianie
- a01_podstawy
- a02_liczby
- a03_overloading_overriding
- a07_varargs
- p18_zagniezdzone
- p19_enkapsulacja
- v1_brak_enkapsulacji
- v3_przed_zmiana
- v4_po_zmianie
- p20_normalne_klasy
- p21_wyjatki
- zasoby
- p22_enum
- p23_record
- p29_refleksja
- p30_object
- p31_tablice
- p32_kolekcje
- a_lista
- b_kolejka
- c_zbior
- d_slownik
- e_iteratory
- s_sortowanie
- p33_generyki
- p34_tekst
- a_string
- b_builder
- r_regexp
- p57_http
package pcz.p29_refleksja;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Parameter;
import java.util.Scanner;
public final class PokazRefleksji {
private final Scanner sc;
private Class<?> c = null;
private Object o = null;
PokazRefleksji() {
sc = new Scanner(System.in);
}
private String menu() {
System.out.println();
System.out.println("Current class: " + c);
System.out.println("Current object: " + o);
System.out.println("\nChoose action:");
System.out.println("q - quit");
if(c == null) {
System.out.println("c - choose class");
} else {
System.out.println("c - change class");
System.out.println("p - print general info about current class");
System.out.println("lf - list fields of current class");
System.out.println("lm - list methods of current class");
System.out.println("lc - list constructors of current class");
System.out.println("o - create object ()");
System.out.println("oc - create object using constructor");
}
return sc.nextLine().trim().toLowerCase();
}
private void changeClass() {
System.out.println("Give the full class name (with package):");
String className = sc.nextLine();
try {
c = Class.forName(className);
System.out.println("Class " + className + " has been loaded.");
o = null;
} catch (ClassNotFoundException e) {
System.out.println("Class " + className + " can not been loaded.");
System.out.println("Exception: " + e);
}
}
private void printInfo() {
System.out.println(c.toGenericString());
System.out.println("Full name: " + c.getName());
System.out.println("Simple name: " + c.getSimpleName());
System.out.println("Canonical name: " + c.getCanonicalName());
if(c.getSuperclass() != null) {
System.out.println("superclass: " + c.getSuperclass().getName());
}
if(c.getEnclosingClass() != null) {
System.out.println("enclosing class: " + c.getEnclosingClass().getName());
}
if(c.isArray()) {
System.out.println("This is array of " + c.getComponentType());
}
}
private void listFields() {
System.out.println("All accessible fields:");
for(Field field : c.getFields()) {
describeField(field);
}
System.out.println();
System.out.println("All fields declared in this class:");
for(Field field : c.getDeclaredFields()) {
describeField(field);
}
}
private void listMethods() {
System.out.println("All accessible methods:");
for(Method method : c.getMethods()) {
describeMethod(method);
}
System.out.println();
System.out.println("All methods declared in this class:");
for(Method method : c.getDeclaredMethods()) {
describeMethod(method);
}
}
private void listConstructors() {
System.out.println("All accessible methods:");
for(Constructor<?> constr : c.getConstructors()) {
describeConstructor(constr);
}
System.out.println();
}
private void describeField(Field field) {
System.out.print(" * " + field.getName() + " : " + field.getGenericType());
System.out.println(" / " + Modifier.toString(field.getModifiers()));
}
private void describeMethod(Method method) {
System.out.print(" * " + method.getName());
System.out.println(" / " + Modifier.toString(method.getModifiers()));
System.out.println(" parameters:");
for (Parameter parameter : method.getParameters()) {
System.out.println(" - " + parameter.getName() + " : " + parameter.getType());
}
System.out.println(" result type: " + method.getReturnType());
}
private void describeConstructor(Constructor<?> constr) {
System.out.print(" * " + constr);
System.out.println(" / " + Modifier.toString(constr.getModifiers()));
System.out.println(" parameters:");
for (Parameter parameter : constr.getParameters()) {
System.out.println(" - " + parameter.getName() + " : " + parameter.getType());
}
}
private void createObject() {
try {
Constructor<?> defaultConstructor = c.getConstructor();
o = defaultConstructor.newInstance();
System.out.println("New object has been created");
System.out.println(o);
} catch (NoSuchMethodException e) {
System.out.println("This class has no default constructor. " + e);
} catch (Exception e) {
System.out.println(e);
}
}
private void invokeConstructor() {
Constructor<?>[] constructors = c.getConstructors();
if(constructors.length == 0) {
System.out.println("No constructors available.");
return;
}
System.out.println("Choose one of the constructors:");
for (int i = 0; i < constructors.length; i++) {
System.out.printf(" * %2d : %s\n", i, constructors[i]);
}
System.out.print("Give the number: ");
while(!sc.hasNextInt()) {
sc.next();
}
int choice = sc.nextInt();
sc.nextLine();
try {
Constructor<?> constructor = constructors[choice];
Parameter[] parameters = constructor.getParameters();
Object[] args = new Object[constructor.getParameterCount()];
for (int i = 0; i < parameters.length; i++) {
Parameter parameter = parameters[i];
System.out.println("Give value of type " + parameter.getType() + " for parameter " + parameter.getName());
args[i] = sc.nextLine();
}
o = constructor.newInstance(args);
System.out.println("New object has been created");
System.out.println(o);
} catch (Exception e) {
System.out.println("Cannot create object " + e);
}
}
void run() {
loop: while(true) {
String action = menu();
switch(action) {
case "q" : break loop;
case "c" : changeClass(); break;
case "p" : printInfo(); break;
case "lf" : listFields(); break;
case "lm" : listMethods(); break;
case "lc" : listConstructors(); break;
case "o" : createObject(); break;
case "oc" : invokeConstructor(); break;
}
}
System.out.println("bye");
}
public static void main(String[] args) {
new PokazRefleksji().run();
}
}
package pcz.p29_refleksja;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import pcz.p29_refleksja.klasy.ABC;
import pcz.p29_refleksja.klasy.Konto;
import pcz.p29_refleksja.klasy.Osoba;
public class PrzykladRefleksji {
public static void main(String[] args) throws Exception {
// Różne sposoby uzyskiwania obiektu Class
Class<?> klasa = Osoba.class;
Class<Osoba> klasa1 = Osoba.class;
Osoba osoba = new Osoba();
Class<?> klasa2 = osoba.getClass();
if(klasa2 == klasa1) {
System.out.println("To jest ta sama klasa");
}
try {
Class<?> klasa3 = Class.forName("pcz.p29_refleksja.klasy.Osoba");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
System.out.println("Obiekt klasy: " + klasa);
System.out.println("name: " + klasa.getName());
System.out.println("simpleName: " + klasa.getSimpleName());
System.out.println("nadklasa: " + klasa.getSuperclass().getName());
System.out.println();
System.out.println("Lista konstruktorów");
for (Constructor<?> constructor : klasa.getConstructors()) {
System.out.println(constructor);
}
System.out.println("Tworzę obiekt za pomocą konstr. bezarg.");
Object obiekt1 = klasa.newInstance();
System.out.println("Utworzyłem obiekt: " + obiekt1);
System.out.println("Klasa obiektu: " + obiekt1.getClass());
System.out.println();
System.out.println("Tworzę obiekt za pomocą konstruktora z argumentami");
Constructor<?> constructor3 = klasa.getConstructor(String.class, String.class, int.class);
Object obiekt2 = constructor3.newInstance("Ola", "Nowakowska", 33);
System.out.println("Utworzyłem obiekt: " + obiekt2);
System.out.println("Klasa obiektu: " + obiekt2.getClass());
System.out.println();
System.out.println("Zmienne klasy Osoba:");
for (Field field : klasa.getFields()) {
System.out.println(" + " + field.getName() + " : " +field.getType().getName());
}
System.out.println("Zmienne zadeklarowane w Osoba:");
for (Field field : klasa.getDeclaredFields()) {
System.out.println(" + " + field.getName() + " : " +field.getType().getName());
}
System.out.println("Metody klasy Osoba:");
for (Method field : klasa.getMethods()) {
System.out.println(" * " + field.getName());
}
System.out.println("Metody zadeklarowane w klasie Osoba:");
for (Method field : klasa.getDeclaredMethods()) {
System.out.println(" # " + field.getName());
}
System.out.println();
Field poleImie = klasa.getField("imie");
// System.out.println(poleImie);
poleImie.set(obiekt1, "Ala");
Field poleNazwisko = klasa.getField("nazwisko");
poleNazwisko.set(obiekt1, "Kowalska");
Field poleWiek = klasa.getField("wiek");
poleWiek.setInt(obiekt1, 44);
System.out.println("Ustawiłem pola, teraz obiekt wypisuje się jako:");
System.out.println(obiekt1);
System.out.println("nazwisko = " + poleNazwisko.get(obiekt1));
System.out.println();
for (Field field : klasa.getDeclaredFields()) {
if("haslo".equals(field.getName())) {
try {
field.set(obiekt1, "abc123");
System.out.println("Ustawiłem hasło " + field.get(obiekt1));
} catch(Exception e) {
System.out.println("Nie udało się ustawić prywatnego hasła po raz pierwszy");
System.out.println(e);
}
try {
System.out.println("Próbuję uzyskać dostęp za pomocą setAccessible");
field.setAccessible(true); // lub trySetAccessible() bez ryzyka wyjątku
field.set(obiekt1, "cba321");
System.out.println("Ustawiłem hasło " + field.get(obiekt1));
} catch(Exception e) {
System.out.println("Nie udało się ustawić prywatnego hasła po raz drugi");
System.out.println(e);
}
}
}
System.out.println();
System.out.println("Wywołam metodę:");
Method metodaPrzedstaw = klasa.getMethod("przedstawSie");
metodaPrzedstaw.invoke(obiekt1);
System.out.println();
// Poniżej widać co daje typ generyczny w Class i Constructor
// Dzięki niemu newInstance zwraca obiekt Konto bez żadnego rzutowania
System.out.println("Teraz utworzę obiekt klasy Konto");
Class<Konto> klasaKonto = Konto.class;
Constructor<Konto> constructorKonto = klasaKonto.getConstructor(int.class, int.class, Osoba.class);
Konto konto = constructorKonto.newInstance(123, 1000, obiekt1);
System.out.println(konto);
// mógłbym wywołać metodę w zwykły sposób:
konto.wplata(100);
// ale zobaczmy też jak wywołuje się metodę z parametrami przez API refleksji:
System.out.println("Teraz wywołam metodę wplata");
Method metodaWplata = klasaKonto.getMethod("wplata", int.class);
System.out.println(metodaWplata);
metodaWplata.invoke(konto, 300);
System.out.println(konto);
System.out.println();
Method metodaGetSaldo = klasaKonto.getMethod("getSaldo");
System.out.println(metodaGetSaldo);
Object wynik = metodaGetSaldo.invoke(konto);
System.out.println("getSaldo zwróciło w wyniku: " + wynik.getClass() + " " + wynik);
System.out.println();
System.out.println("A teraz przegląd informacji z deklaracji w klasie ABC");
Class<ABC> klasaABC = ABC.class;
System.out.println("Zadeklarowane pola:");
for (Field field : klasaABC.getDeclaredFields()) {
System.out.println(" * " + field);
System.out.println(" nazwa: " + field.getName());
System.out.println(" typ: " + field.getType());
if(field.getType().getDeclaringClass() != null) {
System.out.println(" Typ zadeklarowany wewnątrz: " + field.getType().getDeclaringClass());
}
Type genericType = field.getGenericType();
// wynikiem jest ParameterizedType tylko jeśli typ jest faktycznie sparametryzowany
if(genericType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) genericType;
System.out.println(" To jest typ generyczny " + genericType);
System.out.println(" Parametry typowe:");
for (Type type : parameterizedType.getActualTypeArguments()) {
System.out.println(" > " + type);
}
}
Annotation[] adnotacje = field.getDeclaredAnnotations();
if(adnotacje != null && adnotacje.length > 0) {
System.out.println(" Adnotacje:");
for(Annotation an : adnotacje) {
System.out.println(" " + an);
Class<? extends Annotation> annoType = an.annotationType();
System.out.println(" parametry adnotacji:");
for (Method annoMethod : annoType.getDeclaredMethods()) {
System.out.println(" / " + annoMethod.getName() + " = " + annoMethod.invoke(an));
}
}
}
System.out.println();
}
}
}
package pcz.p29_refleksja.klasy;
import java.util.List;
import java.util.Map;
public class ABC {
int i;
String s;
List<String> lista;
Map.Entry<String, Osoba> entry;
@SuppressWarnings("all")
String element;
@Deprecated
public String metoda(String arg) {
return "Hello " + arg;
}
}
package pcz.p29_refleksja.klasy;
public class BrakSrodkow extends Exception {
public BrakSrodkow() {
super();
}
public BrakSrodkow(String message) {
super(message);
}
}
package pcz.p29_refleksja.klasy;
public class Konto {
// final oznacza, że pole numer jest ustawiane w tworzonym obiekcie, a później się nie zmienia
private final int numer;
private int saldo;
private Osoba wlasciciel;
public Konto(int numer, int saldo, Osoba wlasciciel) {
if(saldo < 0) {
throw new IllegalArgumentException("saldo nie może być ujemne");
}
if(wlasciciel == null) {
throw new IllegalArgumentException("właściciel konta nie może być null");
}
this.numer = numer;
this.saldo = saldo;
this.wlasciciel = wlasciciel;
}
// "encapsulation" - "hermetyzacja"
// Tworząc klasę ukrywamy pola tej klasy jako prywatne
// i dajemy dostęp tylko w takim zakresie, jak chcemy.
// Tutaj: odczyt wszystkich pól,
// ale nie dajemy setterów do:
// - numeru - bo "numer nigdy się nie zmienia"
// - saldo - bo o zmianie salda decydują operacje biznesowe wykonywane na koncie (wplata/wyplata/przelew)
public Osoba getWlasciciel() {
return wlasciciel;
}
// Dzięki enkapsujacji mogę też pilnować, aby na zmiennych były wpisane poprawne wartości
// Np.: nie dopuszczamy wlaściciela null
// Dzięki wyjątkom mogę nie dopuścić do wykonania operacji, która zepsułaby wartość zmiennej w obiekcie
public void setWlasciciel(Osoba wlasciciel) {
if(wlasciciel == null) {
throw new IllegalArgumentException("właściciel konta nie może być null");
}
this.wlasciciel = wlasciciel;
}
public int getNumer() {
return numer;
}
public int getSaldo() {
return saldo;
}
public void wplata(int kwota) {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " we wpłacie");
}
saldo += kwota;
}
public void wyplata(int kwota) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
if(kwota > saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
saldo -= kwota;
}
public void przelew(int kwota, Konto kontoDocelowe) throws BrakSrodkow {
if(kwota < 0) {
throw new IllegalArgumentException("Ujemna kwota " + kwota + " w wypłacie");
}
if(kwota > this.saldo) {
throw new BrakSrodkow("Brak środków na koncie nr " + numer);
}
this.saldo -= kwota;
kontoDocelowe.saldo += kwota;
// Obiekt ma dostęp do zmiennych prywatnych innych obiektów tej samej klasy
}
public String toString() {
return "Konto nr " + numer + ", saldo: " + saldo + ", wł.: " + wlasciciel;
}
}
package pcz.p29_refleksja.klasy;
public class Osoba {
public String imie, nazwisko;
public int wiek;
private String haslo;
public Osoba() {
}
public Osoba(String imie, String nazwisko, int wiek) {
this.imie = imie;
this.nazwisko = nazwisko;
this.wiek = wiek;
}
public void przedstawSie() {
System.out.println("Nazywam się " + imie + " " + nazwisko + " i mam " + wiek + " lat.");
}
public String toString() {
return imie + " " + nazwisko + " (" + wiek + " lat)";
}
private void metodaPrywatna() {
}
}
package pcz.p29_refleksja.sklep_model;
import java.util.List;
public class Customer extends WspolnaNadklasa {
private static final long serialVersionUID = 1L;
private String customerEmail;
private String address;
private String city;
private String customerName;
private String phoneNumber;
private String postalCode;
private List<Order> orders;
public Customer() {
}
public String getCustomerEmail() {
return this.customerEmail;
}
public void setCustomerEmail(String customerEmail) {
this.customerEmail = customerEmail;
}
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCity() {
return this.city;
}
public void setCity(String city) {
this.city = city;
}
public String getCustomerName() {
return this.customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getPhoneNumber() {
return this.phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getPostalCode() {
return this.postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public List<Order> getOrders() {
return this.orders;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
public Order addOrder(Order order) {
getOrders().add(order);
order.setCustomer(this);
return order;
}
public Order removeOrder(Order order) {
getOrders().remove(order);
order.setCustomer(null);
return order;
}
}
\ No newline at end of file
package pcz.p29_refleksja.sklep_model;
import java.util.Date;
import java.sql.Timestamp;
import java.util.List;
public class Order extends WspolnaNadklasa {
private static final long serialVersionUID = 1L;
private Integer orderId;
private Date deliveryDate;
private Timestamp orderDate;
private String status;
private List<OrderProduct> orderProducts;
private Customer customer;
public Order() {
}
public Integer getOrderId() {
return this.orderId;
}
public void setOrderId(Integer orderId) {
this.orderId = orderId;
}
public Date getDeliveryDate() {
return this.deliveryDate;
}
public void setDeliveryDate(Date deliveryDate) {
this.deliveryDate = deliveryDate;
}
public Timestamp getOrderDate() {
return this.orderDate;
}
public void setOrderDate(Timestamp orderDate) {
this.orderDate = orderDate;
}
public String getStatus() {
return this.status;
}
public void setStatus(String status) {
this.status = status;
}
public List<OrderProduct> getOrderProducts() {
return this.orderProducts;
}
public void setOrderProducts(List<OrderProduct> orderProducts) {
this.orderProducts = orderProducts;
}
public OrderProduct addOrderProduct(OrderProduct orderProduct) {
getOrderProducts().add(orderProduct);
orderProduct.setOrder(this);
return orderProduct;
}
public OrderProduct removeOrderProduct(OrderProduct orderProduct) {
getOrderProducts().remove(orderProduct);
orderProduct.setOrder(null);
return orderProduct;
}
public Customer getCustomer() {
return this.customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}
\ No newline at end of file
package pcz.p29_refleksja.sklep_model;
import java.math.BigDecimal;
public class OrderProduct extends WspolnaNadklasa {
private static final long serialVersionUID = 1L;
private BigDecimal actualPrice;
private BigDecimal actualVat;
private Integer quantity;
private Order order;
private Product product;
public OrderProduct() {
}
public BigDecimal getActualPrice() {
return this.actualPrice;
}
public void setActualPrice(BigDecimal actualPrice) {
this.actualPrice = actualPrice;
}
public BigDecimal getActualVat() {
return this.actualVat;
}
public void setActualVat(BigDecimal actualVat) {
this.actualVat = actualVat;
}
public Integer getQuantity() {
return this.quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public Order getOrder() {
return this.order;
}
public void setOrder(Order order) {
this.order = order;
}
public Product getProduct() {
return this.product;
}
public void setProduct(Product product) {
this.product = product;
}
}
\ No newline at end of file
package pcz.p29_refleksja.sklep_model;
import java.math.BigDecimal;
public class Product extends WspolnaNadklasa {
private Integer productId;
private String description;
private BigDecimal price;
private String productName;
private BigDecimal vat;
public Product() {
}
public Integer getProductId() {
return this.productId;
}
public void setProductId(Integer productId) {
this.productId = productId;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
public BigDecimal getPrice() {
return this.price;
}
public void setPrice(BigDecimal price) {
this.price = price;
}
public String getProductName() {
return this.productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public BigDecimal getVat() {
return this.vat;
}
public void setVat(BigDecimal vat) {
this.vat = vat;
}
}
\ No newline at end of file
package pcz.p29_refleksja.sklep_model;
import java.math.BigDecimal;
public class Test {
public static void main(String[] args) {
Product product = new Product();
product.setProductId(123);
product.setProductName("pralka");
product.setDescription("Pralka bardzo dobrze pierze.");
product.setPrice(new BigDecimal("1390.90"));
product.setVat(new BigDecimal("0.23"));
System.out.println(product);
}
}
package pcz.p29_refleksja.sklep_model;
import java.lang.reflect.Field;
abstract class WspolnaNadklasa {
@Override
public String toString() {
StringBuilder result = new StringBuilder();
Class<? extends WspolnaNadklasa> klasa = this.getClass();
result.append(klasa.getSimpleName()).append(" [");
int fieldNo = 0;
for(Field field: klasa.getDeclaredFields())
try {
if(fieldNo++ > 0) {
result.append(", ");
}
Object value;
if(field.trySetAccessible()) {
value = field.get(this);
} else {
value = "!";
}
result.append(field.getName()).append('=').append(value);
} catch(IllegalArgumentException | IllegalAccessException e) {
System.err.println(e);
}
result.append("]");
return result.toString();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment