Uzyskiwanie dostępu do pola będącego obiektem innej klasy za pomocą refleksji

0

Mam taki problem - mamy klasy do których musimy dostać się za pomocą refleksji do pól publicznych:

class Human {
   public int age = 30;
   public String name = "JakisLudzik";
   public BankAccount account = new BankAccount();
}
class BankAccount {
   public Double balance;
   public Double loan;
   public BankAccount() {
        balance = 3000.0;
        loan = 1000.0; 
   }
}

I za pomocą refleksji powinniśmy otrzymać wynik:

class Human
int age = 30
java.lang.String name = JakisLudzik
BankAccount account = {
  java.lang.Double balance = 3000.0
  java.lang.Double loan = 1000.0
}
 

No i mój problem polega na tym, że nie za bardzo wiem jak dostać się do klasy BankAccount za pomocą refleksji. Oczywiście sam dostęp do pól problemem nie jest, zrobiłem to wykorzystując Field[] z tym, że w momencie odwoływania się do klasy BankAccount - dostaję referencję. No i moje pytanie jest takie - jak odwołać się do wnętrzności klasy BankAccount mając referencję do jej obiektu w klasie Human. Dodatkowo może zajść sytuacja, że np. w klasie BankAccount byłby kolejny obiekt jakiejś innej klasy i do niego także trzeba by było się odwołać. Oczywiście wrappery do prymitywów i klasa String powinny zwracać wynik od razu - bez zaglądania do środka.

0
account.getClass();

?

0

No tak, tylko cały problem w tym, że ja nie znam klasy, którą dostanę do zbadania, więc nie za bardzo mogę odwołać się do pola account, ta sytuacja jest tylko przykładowa.

0

Zainteresowało mnie to zagadnienie. Co Twój program dostanie na wejściu: nazwę klasy, obiekt tej klasy czy też obiekt, a klasa jest nieznana.

1

To, co próbujesz zrobić to się nazywa serializacja i nie potrzebujesz do tego - jawnie - refleksji. Jeśli forma danych nie jest ważna (tzn. może być XML/JSON/jakiś inny standard), a po prostu chcesz mieć możliwość zapisywania danych do pliku to możesz użyć jednej z miliona bibliotek do tego służących.

Jeśli forma musi być taka, jak przedstawiona przez Ciebie to można zrobić to mniej więcej w ten sposób:

	public static void main(String[] args){
		Object o = new MyObject();
		printFields(o);
	}

	private static void printFields(Object o){
        	Stream.of(o.getClass().getDeclaredFields())
                	.peek(f -> f.setAccessible(true))
                	.map(f -> getValue(f, o))
                	.forEach(s -> System.out.println(s));
	}

	private static String getValue(Field f, Object o){
        	String stringValue = null;
        	try {
            		Object val = f.get(o);
            		if(val == null){
                		stringValue = "null";
            		} else {
                		stringValue = val.toString();
            		}
        	} catch (IllegalAccessException e) {
            		e.printStackTrace();
        	}

        	return f.getType().toString() + " " + f.getName() + "=" + stringValue;
	}

Całości oczywiście nie podam, bo to IMO trochę głupiego robota - trzeba sprawdzać, czy coś jest kolekcją, dodać odpowiednie if-y na String, Integer, obsłużyć wypisywanie obiektów itp.

Edit: być może krok f.setAccessible(true) w Twoim przypadku jest zbędny.

0

Dzięki za odpowiedź :).
A jeśli o zadanie chodzi. Mam do zrobienia program, który analizuje klasy za pomocą refleksji i przetwarza je na dokumenty XML. Czyli w funkcji do badania pól dostaję tylko obiekt (którego z góry nie znam - jego wnętrze ma przeanalizować dopiero mój program), dlatego nie mogę się bezpośrednio odwoływać do konkretnych pól. Niestety nie mogę skorzystać z konkretnych bibliotek, bo mam to zrealizować mechanizmem refleksji. Ja trochę kombinując rozwiązałem to rekurencją, tylko jest jeszcze taki problem, że przy funkcji rekurencyjnej nie mogę dodawać gałęzi do obiektu Document.

1 użytkowników online, w tym zalogowanych: 0, gości: 1