Zwei Objekte einer Klasse beeinflussen sich gegenseitig

Hallo,

ich habe eine Klasse Profile.java

//     Auschnitt...
	private float amount;

	public float getAmount() {
		return amount;
	}
	public void setAmount(float amount) {
		this.amount = amount;
	}
}```

In der Klasse MyActions.java erzeuge ich zwei Objekte von Profile:
```public class MyActions {
	private Profile profile;
	private Profile profileEdit;
	public MyActions(){
		profile = new Profile();
		profileEdit = new Profile();
	}
	public Profile getProfile() {
		return profile;
	}
	public void setProfile(Profile profile) {
		this.profile = profile;
	}
	public Profile getProfileEdit() {
		return profileEdit;
	}
	public void setProfileEdit(Profile profileEdit) {
		this.profileEdit = profileEdit;
	}
}```

in einer dritten Klasse nutze ich die Objekte.
Aber wenn ich in das eine Objekt ein Wert für Amount reinschreibe, so ist dieser dann auch bei dem anderen Objekt zu finden.
```MyActions act = new MyActions(); // (...verkürzt, MyActions ist ein Singleton und wird mit getInstance abgeholt.)
Log.d(TAG, "B p: " + act.getProfile().getAmount() + ", pe: " + act.getProfileEdit().getAmount());  // B p: 0.0, pe: 0.0
act.getProfileEdit().setAmount(99.0);
Log.d(TAG, "C p: " + act.getProfile().getAmount() + ", pe: " + act.getProfileEdit().getAmount()); // C p: 99.0, pe: 99.0```

**Wie kann das sein, dass die Zahl in beide Objekte geschrieben wird, statt nur in profileEdit?**

Mein bester Tipp: amount ist in Wirklichkeit static

bye
TT

  1. Singletons sind böse.
  2. Wenn du schon code postest, dann bitte vollständig. Ich tippe mal dein Problem liegt da wo “// Auschnitt…” steht.

@bERt0r :

zu 2.) da wo // Ausschnitt steht sind lediglich weitere 20 Variablenwerte mit Gettern und Settern, sonst nix.

@Timothy_Truckle :
amount ist nicht statisch.
private float amount;

Profile ist nicht statisch.
MyActions ist nicht statisch.
MyActions.profile und . profileEdit sind nicht statisch.

Zeig doch mal bitte die gesamte Klasse MyActions, wie verwaltest du denn den Singleton?

kopier ich deinen Code in eclipse und mach dein MyActions ebenso ein Singleton, so funktioniert es und die beiden sind unterschiedlich.

Also muss dein Problem in den Stellen liegen, die du ausgelassen hast

MyActions:

package com.name.data;

public class MyActions {
	
	private static final String TAG = "MyActions";
	private static MyActions instance = null;

	private boolean isTurntable, isSupply, isDoser, isCapper, isDebugging, 
	 isManu,  isAuto, isSetup, isHelp, 
	 isStartAllUnit, isStartSelectedUnit, isCounterCounting;
	private boolean forwardContinuous, backwardContinuous, forwardInterval, backwardInterval;
	private boolean loginSuperUser, loginAdmin;
	private boolean isJustStarted, isCounterService;
	private int language, 
	doserTurnBackMax, doserManuSpeed, doserManuSpeedMax, doserManuTurnBack, doserManuTurnBackMax, 
	timeOfRoutineService, partSteps, maxPart;
	private int count = 0, part = 0;
	private long durationLongTouch;
	private String currentProfile, pwSuperUser, pwAdmin, prefLocale;
	private String [] listOfProfiles, listOfPumps, listOfDensitys, listLanguages;
	private SelectedMainMenuItem selectionMainMenuItem;
	private SelectedSubMenuItem selectionSubMenuItem;
	private SelectedRotation selectionRotation;
	private AmountUnit amountUnit;
	private HeightUnit heightUnit;
	private Density density;
	private Pump pump;
	private Filling filling;
	private Profile profile;
	private Profile profileEdit;
	private MySqlAccess mySqlAccess;
	private Context context;
	
	/**
	 * Standartkonstruktor der Singleton-Klasse. Diesen NIEMALS direkt aufrufen, sonder immer nur MyActions.getInstance().
	 * Beim Starten der App zu aller erst MyActions.prepareInstance(this); aufrufen.
	 */
	public MyActions(){
		Log.d(TAG, "MyActions()");
		if ( instance == null ){
			Log.e(TAG, "No no, das hätte nicht passieren dürfen!");
		}
	}
	
	/**
	 * Hierin wird die einzige Instanz dieser Klasse erzeugt
	 * und anschliessend die initialisiert mit Werten (init().
	 * @param context
	 */
	private MyActions(Context context){
		Log.d(TAG, "MyActions(Contextcontext)");		
		init(context);
	}
	
	/**
	 * <strong>public static MyActions getInstance()</strong><br />
	 * Gibt die einzige Instanz dieser Klasse zurück.
	 * @return (MyAction) - Instanz
	 */
	public static MyActions getInstance(){
		if ( instance == null ){
			instance = new MyActions();
		}
		return instance;
	}
	
    /**
     * Statische Methode, erzeugt die einzige Instanz dieser Klasse.
     */
    public static void prepareInstance(Context context) {
    	Log.d(TAG, "1. prepareInstance(Context context)");
    	if (instance == null){
    		instance = new MyActions(context);
    	}
    }
	
	private void init(Context context){
		Log.d(TAG, "init(Context context)");
		this.context = context;
		context.getApplicationContext().registerReceiver(mReceiver, new IntentFilter(BottleAnimation.ACTION_BROADCAST));
		context.getApplicationContext().registerReceiver(mReceiver, new IntentFilter(Counter.ACTION_BROADCAST));
		// ABGFRAGE DES LETZTEN GENUTZTEN PROFILES
		SharedPreferences settings = context.getSharedPreferences("pref", 0);
		setCurrentProfile( settings.getString("currentProfile", "") );
		amountUnit = new AmountUnit();
		heightUnit = new HeightUnit();
		density = new Density();
		pump = new Pump();
		filling = new Filling();
		profile = new Profile();
		profileEdit = new Profile();
		setJustStarted(true);
		setDebugging(false);
		mySqlAccess = new MySqlAccess(context, this);		
	}

	
	// ES FOLGEN ALLE GETTER UND SETTER
}```

Alle Methoden, die bei dieser Aktion unberührt bleiben, also nicht aufgerufen werden, habe ich raus genommen. Darin enthalten sind zB.Services (onReceive). Ebenso habe ich die Getter und Setter raus genommen.

ich sehe gerade:
public static MyActions getInstance()
und 
public static void prepareInstance(Context context)

Hat das mit meinem Problem zu tun?
Was kann ich tun?

abgesehen davon, ein Singleton mit public konstruktor und zwei init methoden ?

Nein das ist kein Singleton…

Ich kann MyActions auch private machen.
Und die prepareInstance() wird beim Start der App einmalig aufgerufen, bevor das erste mal getInstance() angefordert wird.
Ein Singleton kann man vielleicht so oder so schreiben (ich habe mitbekommen, dass es sehr unterschiedliche Meinungen dazu gibt).

Aber egal wie es aussieht, ich wundere mich trotz dem, dass die eine Variable in beiden Objekten auftaucht.

Versuch mal:``` MyActions act = new MyActions(); // (…verkürzt, MyActions ist ein Singleton und wird mit getInstance abgeholt.)
Log.d(TAG, "B p: " + act.getProfile().getAmount() + ", pe: " + act.getProfileEdit().getAmount()); // B p: 0.0, pe: 0.0
if(act.getProfileEdit() == act.getProfile())
{
Log.d(“Das riecht nach Ärger”);
}
act.getProfileEdit().setAmount(99.0);
Log.d(TAG, "C p: " + act.getProfile().getAmount() + ", pe: " + act.getProfileEdit().getAmount()); // C p: 99.0, pe: 99.0


Ausserdem würd ich mal die getter und setter überprüfen...

[QUOTE=bERt0r]Versuch mal:
if(act.getProfileEdit() == act.getProfile())
{
Log.d(„Das riecht nach Ärger“);
}
[/QUOTE]
Antwort: Das riecht nach Ärger

Das hab ich, die stehen auch oben in diesem Thread (copy `n paste).

[QUOTE=frankmehlhop]Antwort: Das riecht nach Ärger[/QUOTE]Du bekommst hier also tatsächlich das selbe Objekt zurück. Die Schlussfolgerung ist, dass einer der Getter das falsche Property zurück gibt…

bye
TT

Die Getter geben jeweils profile und profileEdit zurück.
MyActions:

		return profile;
	}
	public void setProfile(Profile profile) {
		this.profile = profile;
	}
	public Profile getProfileEdit() {
		return profileEdit;
	}
	public void setProfileEdit(Profile profileEdit) {
		this.profileEdit = profileEdit;
	}```

An ein oder zwei Stellen mache ich Zuweisungen die so aussehen:
```act.setProfileEdit(act.getProfile());```
Damit will ich erreichen, dass in profileEdit die selben Variablenwerte geschrieben werden, welche profile bereits besitzt.
Statt dessen könnte ich auch schreiben:
act.getProfileEdit().setAmount(act.getProfile().getAmount());
act.getProfileEdit().setName(act.getProfile().getName());
usw. für die weiteren 12 Variablen...

Kann es mit dieser Zuweisung zu tun haben???

Ja klar weil du die die Variable profileEdit neu setzt und nicht nur deren Werte.
Wenn du nur die Werte von dem einen Profil in das andere übernehmen willst musst du dies so machen wie du es gerade geschrieben hast.

YES!!! :slight_smile:

ich habe meiner Klasse MyActions zwei Methoden hinzugefügt:

	/**
	 * Das Objekt profile erhälte eine Kopie aller Werte von profileEdit. 
	 */
	public void setProfileLikeProfileEdit(){
		profile.setAmount(profileEdit.getAmount());
		profile.setAmountUnit(profileEdit.getAmountUnit());
		profile.setCalibration(profileEdit.getCalibration());
                ...
	}
	/**
	 * Das Objekt profileEdit erhält eine Kopie aller Werte von profile.
	 */
	public void setProfileEditLikeProfile(){
		profileEdit.setAmount(profile.getAmount());
		profileEdit.setAmountUnit(profile.getAmountUnit());
		profileEdit.setCalibration(profile.getCalibration());
                ...
	}```

diese rufe ich nun zum kopieren auf und es funktioniert so, wie man es sich vorstellt. 

Ich danke Euch allen für Eure Hilfe und Hinweise!!!