instanceof vermeiden

Status
Nicht offen für weitere Antworten.

Johannes L.

Aktives Mitglied
Hallo,

wie kann man am besten instanceof Operatoren vermeiden? Ich rufe Methoden auf, wobei man innerhalb der Methode prüfen muss um welches Objekt es sich handelt um nur richtig zu casten und halt zu schauen welches Objekt null ist.

Also innerhalb der Methode:

Code:
	/**
	 * Get the status-line and the Headers.
	 * 
	 * @param to_client
	 * 	Output text stream.
	 * @param method
	 *  The method used.
	 */
	private void getResponseHeader(PrintWriter to_client, Object method)
	{
		Header[] headers = null;
		
		if(method instanceof GetMethod)
		{
			to_client.print(((GetMethod) method).getStatusLine().toString()+"\r\n");
			to_client.flush();
		
			headers = ((GetMethod) method).getResponseHeaders();
		}
		else if(method instanceof HeadMethod)
		{
			to_client.print(((HeadMethod) method).getStatusLine().toString()+"\r\n");
			to_client.flush();
			
			headers = ((HeadMethod) method).getResponseHeaders();
		}
		else if(method instanceof PostMethod)
		{
			to_client.print(((PostMethod) method).getStatusLine().toString()+"\r\n");
			to_client.flush();
			
			headers = ((PostMethod) method).getResponseHeaders();
		}
		
		for(Header header : headers)
		{
			logger.debug("Header: "+header.toString());
			to_client.print(header.toString());
			to_client.flush();
		}
		
		to_client.print("\r\n");
		to_client.flush();
	}

Wobei ich mir da gar nicht so wirklich sicher bin, ob es überhaupt Sinn macht das in eine Methode auszulagern oder eher gleich in jeden Case-Block zu schreiben.

Viele Grüsse,
Johannes
 
Code:
   private void getResponseHeader(PrintWriter to_client, HttpMethod method)
   {
      Header[] headers = method.getResponseHeaders();
      
        to_client.print(method.getStatusLine().toString()+"\r\n");
         to_client.flush();
      
      for(Header header : headers)
      {
         logger.debug("Header: "+header.toString());
         to_client.print(header.toString());
         to_client.flush();
      }
      
      to_client.print("\r\n");
      to_client.flush();
   }
?

edit: außerdem ist die methode sinnlos benannt
edit2: und warum schreibst du das ganze zeug selber in den stream :?:
 
wenn das deine eigenen Klassen sind, dann fasse sie in ein Interface zusammen
mit Operationen wie getType() oder isTypePostMethod() oder ähnliches,
dann kannst du einfache ints oder boolean vergleichen,
was etwas performanter ist,

letztlich wirst du aber um das if-else-Konstrukt + Cast nicht vorbeikommen, falls du das ganze nicht generell generischer lösen kannst,

wenn z.B. getResponseHeaders() im Interface angegeben wäre,
müsstes du wohl gar nicht casten/ nach den Typ fragen
 
Naja, es ist ein Proxyserver und ich muss ja die ganzen Daten, die ich vom httpclient kriege an den Client weiterschicken. Wie kann ich das sonst weiterleiten?
 
JEDE Typabfrage ist eine Kapitulation vor der Objektorientierung - und getClass().getName() ist sogar noch ein bißchen schlimmer :autsch: Aber Roar hat die Lösung ja schon genannt :roll:
 
Marco13 hat gesagt.:
JEDE Typabfrage ist eine Kapitulation vor der Objektorientierung..
Trotzdem sollte man instanceof sinnvoll einsetzen.
Jede equals-Methode, die Object#equals überschreibt, sollte z.B. eine solche Typabfrage haben:
Code:
public boolean equals(Object o){
  if(!(o instanceof MyType)){
    return false;
  ...
}
:wink:
 
Soweit ich mich erinnere sind sogar in den original Java-Sourcen von Sun einige "equals" Methoden so implementiert
Code:
public boolean equals(Object otherObject)
{
    try
    {
        ThisClass other = (ThisClass)otherObject;
         ...
    }
    catch (ClassCastException e)
    {
         return false;
    }
}
Ich wollte nur andeuten: Man braucht instanceof nicht. Und wenn doch, dann ist es ein Modellierungs"fehler". ("Fehler" in Anführungszeichen, weil JEDER an irgendeinem Punkt kapituliert, und der Aufwand mit instanceof u.U. um Größenordnungen geringer sein kann, als mit einer "richtigen" Modellierung)
 
Marco13 hat gesagt.:
Soweit ich mich erinnere sind sogar in den original Java-Sourcen von Sun einige "equals" Methoden so implementiert
Code:
public boolean equals(Object otherObject)
{
    try
    {
        ThisClass other = (ThisClass)otherObject;
         ...
    }
    catch (ClassCastException e)
    {
         return false;
    }
}
..
Das würde mich sehr wundern, weil das recht unperformant ist.
Man braucht 'instanceof' wohl doch dazu :wink:

Der 'instanceof' Operator erlaubt es zu festzustellen, ob ein bestimmtes Casten erlaubt ist, ohne es erst zu versuchen.
Da die Perfomance viel besser ist als bei einer ClassCastException, ist es allgemein günstig,
eine 'instanceof' Abfrage zu machen, wenn man nicht sicher ist, ob der Typ einer Referenz so ist, wie man will.
Zuvor sollte man sich allerdings überlegen, ob man vernünftig mit einem ungewollten Typ umgehen kann.
Andernfalls wäre es besser, die Exception werfen zu lassen, um sie auf einer höheren Ebene zu behandeln.
 
Es IST aber so. Nur ... wie oft vergleicht man auch z.B. zwei FontRenderContext-Objekte...? :? Jedenfalls stellt sich für mich dann die Frage, ob "equals" überhaupt mit Objekten unterschiedlicher Klassen aufgerufen werden sollte !? ...
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben