[Java] Wskaźniki do obiektów

0

Cześć.
Mam aplet. Na aplecie mam button. Jak zrobić wskaźnik do tego buttona?

Potrzebuję coś w takim rodzaju:

Wskaznik wsk = new Wskaznik(button1);

...

wsk.setText("Jakis tekst"); //i w tym momencie button1 ma tekst "Jakis tekst"

Chodzi o to, że nie mogę tej operacji przeprowadzić tak: button1.setText(...) z różnych względów.

0

W javie nie ma wskaznikow. Nazwa kazdego obiektu za to jest referencja, czyli tak jakby wskaznikiem ;)
Z jakich wzgledow niby nie mozesz uzywac button1 normalnie?

0

W javie nie ma wskaznikow. Nazwa kazdego obiektu za to jest referencja, czyli tak jakby wskaznikiem ;)
Z jakich wzgledow niby nie mozesz uzywac button1 normalnie?

Z takich, że tych komponentów mam dość dużo i mam dwa wyjścia.

Albo porównywać i zmieniać pewne rzeczy w warunkach za pomocą button1.blabla, z tym, że wtedy zejdzie mi na to ze 3 dni ;), bo sprawdzeń będzie bardzo dużo.
Albo innym sposobem(ze wskaźnikami) przyrównywać w odpowiednim momencie do wskaźników odpowiednie obiekty(adresy) i robić tylko jedno sprawdzenie.

W takim razie, czy da się zadeklarować obiekt, który ma referencję do tego samego adresu, co jakiś button?

0

W takim razie, czy da się zadeklarować obiekt, który ma referencję do tego samego adresu, co jakiś button?

Nie wiem, czy dobrze rozumiem ;)
Jak napiszesz

Button b2 = button1;

to w b2 bedzie referencja do button1, ale w ten sposob wyprodukujesz jeszcze wiecej zmiennych...

0

W takim razie, czy da się zadeklarować obiekt, który ma referencję do tego samego adresu, co jakiś button?

Nie wiem, czy dobrze rozumiem ;)
Jak napiszesz

Button b2 = button1;

to w b2 bedzie referencja do button1, ale w ten sposob wyprodukujesz jeszcze wiecej zmiennych...

Może być. Ale ważne, żeby wskazywało na ten sam adres. To mi zaoszczędzi bardzo dużo roboty

0

Masz jeszcze trzeci sposób. Przemyśleć budowę programu ;)

pzdr,
y.

0

jesli tworzysz buttony to wrzucaj je sobie np. do listy albo tablicy - obmysl jaka tam strukture trzeba... w javie nie ma wskaznikow bo są niepotrzebne i ma to swoje plusy i moze jakis jeden minus........;)

0

w javie ma wskaznikow bo sa niepotrzebne i ma to swoje plusy i moze jakis jeden minus........;)

Jak to nie ma jak sa? W Javie sa wlasciwie TYLKO wskazniki. Jakis baran kiedys nazwal to referencja i wielu tak to pozniej zle nazywa.
Zachowanie wskaznikow w Javie jest duzo blizsze zachowaniu wskaznikow w C++ niz referencji w C++. Tylko ze to sa takie ulepszone wskazniki. Nie trzeba pisac gwiazdki.

0

tak naprawde to nie jest ani odnosnik ani referencja, bo nie mozna wykonywac na nim operacji matematycznych tak jak na wskaznikach z C, a z kolei da sie zrobic pusta referencje co nie jest mozliwe w C. ale raczej bylbym skolnnym nazwania tego referencja, bo nie przechowuje faktycznej informacji o obiekcie a nie potrzeba uzywac operatora wyluskania do jego modyfikacji.
Nie wiem po co tyle krzyku, po prostu referencje w javie roznia sie od referencji w c. Jak komus sie to nie podoba zawsze moze poszukac innego rozwiazania. Np. mój prowadzący do javy nazywal je z kolei odnośnikami.

0

O, ja sie podepne pod pytanie z czyms podobnym. Zalozmy, ze mamy trzy obiekty A,B,C. Obiekty maja pola Integer id;

I teraz tak, jak zrobimy np.
C.id = B.id
B.id = A.id
A.id = new Integer(10);

To nie jest to propagowane "w gore" obiektow (w zalozeniu wszystkie .id powinny sie ustawic na wartosc 10). Chodzi o to, zeby zmiana jednego identyfikatora pociagnela za soba automatyczna zmiane "podlinkowanych" identyfikatorow w niezaleznych obiektach. Z C/C++ nie jestem zbyt dobry, ale z tego co pamietam i rozumiem to mozna by uzyc tutaj wlasnie wskaznikow na dany obszar pamieci, tak ze wszystkie .id wskazywalyby na dokladnie ta sama wartosc nie wazne w ktorym miejscu i jak zmieniana. W Javie to nie wychodzi, bo mimo ze obiekty sa przekazywane przez referencje, to ustawienie jak powyzej powoduje odwolania do przestarzalych obiektow .id i przypisanie obiektowi A nowego id nie wyplywa na poprzednie przypisania.

Jak taki problem rozwiazac w Javie wie ktos moze?

0

Jeżeli wszystkie obiekty pewnej klasy mają mieć tą samą wartość pola id, to niech id będzie polem static.

0

Nie ta sama, chodzi o dynamiczne i progresywne linkowanie obiektow. Zalozmy, ze mamy bitmape z dwoma obszarami pixeli o wartosciach 1, tlo jest na przyklad 0. Progresywnie odczytujemy dane ze strumienia i grupujemy przylegajace pixele linia-po-linii nadajac im ID. I tak np. majac taki uklad:

00110011
00110011
00110010

Idzie tak:

  • linia pierwsza nadajemy pierwszej grupie jedynek id = 1, drugiej id = 2
  • linia druga nadajemy pierwszej grupie id = 3, drugiej id = 4
  • sprawdzamy przy okazji czy jakies grupy z linii wyzej nie stykaja sie z aktualnymi - widac, ze sie stykaja 1 z 3 i 2 z 4. Zmienamy id 1 na 3, 2 na 4
  • lecimy z kolejna linia i nadajemy kolejno id = 5 i id = 6
  • znowu sprawdzamy styki na linii wyzej i zmienamy id 3 na 5 i 4 na 6 ale te ktore wczesniej mialy id 1 i 2 pozostana 3 i 4

Rozwiazanie nie do konca zadowalajace (wydajnosc!):

  • zamiast linkowac wskaznikami/referencjami po prostu przeszukiwac liste znalezionych i zmieniac wszedzie identy ("recznie" czy przez jakas metode - to bez roznicy). Wymaga to niestety dodatkowych petli, przeszukiwania tablic i ogolnie jest malo wydajne. Jako, ze najbardziej czasochlonne jest tutaj przeszukiwanie tablicy, to rozdzielenie tego na watki niczego dobrego nie przyniesie.

Rozwiazanie idealne:

  • tak to wykombinowac, zeby linkowanie id bylo rzeczywiste i automatycznie samo z siebie wskazywalo na ten sam obszar pamieci/obiekt
  • trzeba by tu przemyslec jak to ogarnac zeby wystarczyla jedna zmiana, wskaznik na wskaznik?
0

nie wiem czy jest to dobry pomysl rozwiazania problemu bo w to sie nie zaglebialem, ale jest to sposob na to co prosiles. Any zmiana w jednym polu skutkowala "zmiana" we wszyskich ktore wskazuja na ten sam obiekt

/* przykład klasy IntValue podobnej do Integer, której kod przepisany 
 * z ksiazki Bruce'a Eckel'a Thinking in Java
 * W przeciwienstwie do klasy Integer tutaj zawartosc(int) można edytować
 * Jest to prymitywna klasa bo edycja pola n polega na dostaniu sie do pola.
 * ladniej powinno sie to zrobic setterem i getterem
 */
class IntValue{ 
	int n;
	IntValue(int x) { n = x; }
	public String toString(){
		return Integer.toString(n);
	}
}

class temp{
	IntValue id;
}

public class HelloWorld {
	
	public static void main(String[] args) {
		// tworzymy klasy
		temp C= new temp();
		temp B= new temp();
		temp A= new temp();
		A.id = new IntValue(10); //dla pola id (typu intValue) tworzymy obiekt 
		B.id=A.id; //dla B i C w pole id wpisujemy ten sam adres referencji co jest w polu A.id
		C.id=B.id;
		System.out.print(A.id + " " + B.id + " " + C.id + "\n"); //10 10 10
		
		//zmieniamy zawartosc obiektu A.id tym samym pozostawiajac referencje niezmienione!
		A.id.n=5;
		System.out.print(A.id + " " + B.id + " " + C.id); //5 5 5
	}

}

aha i jeszcze pamietaj ze zamiast:

A.id.n = 5;

zrobienie

A.id= new IntValue(5);

nie zadzialaloby.
bo zamiast zmienic zawartosc obiektu na ktory wskazuje zarowno A.id, B.id jak i C.id stworzylbys nowy obiekt typu IntValue na ktory wskazywalby samotnie A.id
i wtedy zamiast *5 5 5 bys dostal *5 10 10

dlatego nie dalo sie tego przykladu rozwiazac z Integerem. Dostep do jego wartosci jest zabroniony i nie ma on specjalnie metody pozwalajacej ci na jej zmiane, tak jak i kazda inna klasa opakowujaca ktora jest tylko do odczytu.

Mam nadzieje ze pomoglem, pozdrawiam.

0

Obiekty są przekazywane przez referencję, to prawda, ale same referencje przekazywane są już przez wartość.
Twoje rozwiązanie jest tak naprawdę w pierwszym poście tego wątku. Trzeba stworzyć klasę Wskaźnik, która jako taka będzie przechowywała referencję jakiegoś typu, np. Object dla wskaźników dowolnego typu.
Są tylko dwa poważne problemy takiego podejścia:
Po pierwsze "wskaźnik" taki zupełnie nie posiada kontroli typów. Możnaby spróbować zabawić się w typy ogólne. Ale ponieważ te w Javie są zaimplementowane z zacieraniem, więc użyteczność wskaźników typowanych nie dość że byłaby bardzo niska, to katastrofalnie zaciemniałaby kod. A to z takiego powodu, że trzeba by było dodać jeszcze jeden poziom dziedziczenia/implementacji.
W związku z tym ten rodzaj wskaźnika jest jeszcze bardziej niebezpieczny od wskaźników w C/C++, które mają jednak kontrolę typów.

Drugi to efektywność i rozmiar w pamięci... 16 bajtów, to jednak trochę dużo.

No i na koniec to co poniżej, to bardziej referencja niż wskaźnik. Aby zrobić z tego wskaźnik trzebaby pobawić się refleksją dla wykrywania że wskaźnik został zainicjowany kolekcją lub tablicą tak aby można było przypisać referencję pierwszego obiektu i stworzyć metody do arytmetyki wskaźnikami w ramach takiej struktury. Wtedy dopiero możnaby to nazwać inteligentnym wskaźnikiem z dynamicznym sprawdzaniem typów.

package Olamagato;

public class Pointer
{
	public Pointer() {} //wskaźnik pusty
	public Pointer(Object o) { ref = o; } //wskaźnik z inicjacją

	//przypisanie wskazania
	public Pointer set(Object o)
	{
		ref = o;
		return this; //set może zostać użyte w wyrażeniach
	}
	//wyłuskanie wskazania
	public Object get() { return ref; }

	//zamiana wskaźników, brak odpowiednika w C/C++
	public Pointer swap(Pointer swapped)
	{
		Object tmp = ref;
		ref = swapped.get();
		swapped.set(tmp);
		return this;
	}
	private Object ref;
}

package Kandydaci;
import Olamagato.Pointer;

class A
{
	public Pointer id;
}

class B
{
	public Pointer id;
}

class C
{
	public Pointer id;
}

public class TestPointer
{
	public static void main(String[] args)
	{
		int t[] = { 10, 20, 30 };
		A a = new A(); B b = new B(); C c = new C();

		a.id = new Pointer(); //przypisanie referencji
		b.id = a.id; //przepisanie wskaźnika
		c.id = b.id; //przepisanie wskaźnika

		a.id.set(t[0]);
		System.out.printf("a = %d\nb = %d\nc = %d\n",
			a.id.get(), b.id.get(), c.id.get()); //wyłuskanie wskaźników

		b.id.set(t[1]);
		System.out.printf("a = %d\nb = %d\nc = %d\n",
			a.id.get(), b.id.get(), c.id.get()); //wyłuskanie wskaźników

		c.id.set(t[2]);
		System.out.printf("a = %d\nb = %d\nc = %d\n",
			a.id.get(), b.id.get(), c.id.get()); //wyłuskanie wskaźników

		a.id.set(40);
		System.out.printf("a = %d\nb = %d\nc = %d\n",
			a.id.get(), b.id.get(), c.id.get()); //wyłuskanie wskaźników
	}
}

/*
run:
a = 10
b = 10
c = 10
a = 20
b = 20
c = 20
a = 30
b = 30
c = 30
a = 40
b = 40
c = 40
*/
}

ps. Oczywiście zadziałał w tym przykładzie autoboxing, dzięki któremu każdy int z tablicy został opakowany przez Integer, do którego pobrana została referencja.

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