Kann man von einem Interface aus auf die dieses implementierende Klasse zugreifen?

Shams

Aktives Mitglied
Ich bin bei meiner Javalektüre auf die Class–Klasse gestoßen. Meine Idee war daraufhin folgende: Ich dachte, es sei möglich, einen Locator zu schreiben (wie ich ihn bei irgendwelchen kryptischen OSGi-Projekten bereits gesehen habe), welchem man ein Interface als Klasse übergibt, und das dann eine Instanz des implementierten Interface (also der Klasse, die das Interface implementiert) ausgibt. Das stelle ich mir wie hier in der Mainklasse veranschaulicht vor:

Java:
package core;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

         Main m = new Main();
         m.go();
        
	}

	private void go() {
		
			
		 DispatcherService dispatcherservice = (DispatcherService) Locator.locate(DispatcherService.class);
//Hier bekommt die Locatemethode das Interface		 
		 
		 
		 dispatcherservice.setMessage("Here goes my message.");
		 System.out.println(dispatcherservice.getMessage());
	}

}

… und mein Lokator sieht wie folgt aus:

Java:
package core;

public class Main {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

         Main m = new Main();
         m.go();
        
	}

	private void go() {
		
			
		 ServiceImpl dispatcherservice = (ServiceImpl) Locator.locate(Service.class);
		 
		 
		 
		 dispatcherservice.setMessage("Here goes my message.");
		 System.out.println(dispatcherservice.getMessage());
	}

}

Nun habe ich zwei fragen:

Als ich in der Lokatorklasse einen try-ctach-Block austomatisch hinzufügen ließ, ist mir aufgefallen, dass die beiden möglichen Exceptions durch ein | , also durch ein bitweises oder getrennt sind – wieso nicht durch || ?

Zum anderen stelle ich mir die Frage, ob es überhaupt auf irgendeine Art und Weise machbar ist, im Lokator mit der package core;
Java:
public class ServiceImpl implements Service {

	 
	String mMessage = ""; 		

	 
	public void setUserAndMessage(String msg) {
		
		mMessage=msg;
	}

	
	public String getMessage() {
		return mMessage;
	}
  
	
	public void setMessage(String msg) {
		mMessage = msg;
	}
	
	

}
- Methode eine Instanz derjenigen Klasse zu erhalten, die das Interface implementiert. Denn so wie es jetzt ist, bekomme ich natürlich eine Nullpointerexception, da im Lokator nicht eine Instanz der Klasse, sondern eine Interfaceinstanz erzeugt wird.
 
Zuletzt bearbeitet von einem Moderator:
Hey shams,

Ganz ehrlich gesagt verstehe ich die Frage nicht. Du willst einer Variablen vom Typ eines Interfaces den Typ einer Klasse übergeben, welche dieses Interface implementiert? Das ist möglich!
Das mit der Exception ist wirklich einfach zu verstehen. Das was du da mit | meinst sind übrigens logische Operatoren. Dabei gibt es einmal das "normale" Ausschlussverfahren und das "Short curcuit Evaluation" Verfahren. Beim ersten Verfahren "|" werden beide Seiten geprüft. Ergibt die erste Bedingung auf der linken Seite "true" wird obwohl die ganze Bedindung ja schon "true" ergibt trotzdem noch die andere Seite geprüft. Das wird beim anderen Verfahren nicht gemacht. Ergibt die erste Bedindung bereits "true" wird die zweite Bedingung nicht geprüft. Beim "&" Operator ist es genauso, ergibt die erste Bedingung bereits "false" wird die zweite Bedindung nicht geprüft. Das steigert vor allem die Performance und schließt z.B eine NullpointerException aus, wenn die 2. Bedingung auf eine nicht instanziierte Variable zugreift.

Grüße coco07!
 
Zuletzt bearbeitet:
Nachtrag:
Ich habe anscheinend übersehen, dass sich dieser Operator "|" auf das fangen einer Exception bezieht.
Dieser Operator in Bezug auf Exception-Handling bewirkt eigentlich nur, dass du evtl. mehrere Exceptions in einem catch Block behandeln kannst. Nehmen wir mal an, du rufst eine Methode auf, welche eine FileNotFoundException und eine IllegalArgumentException wirft. In beiden Fällen möchtest du dem User eine Fehlermeldung ausgeben, dass die Datei nicht gefunden wurde oder what ever. Dann kannst du in diesem einen Block "catch(FileNotFoundException | IllegalArgumentException e){} diese beiden Exceptions behandeln. Dann ersparst du dir doppelten Code. Dieses Feature kam erst in Java 7 zur Geltung.

grüße coco07!
 
Ganz ehrlich gesagt verstehe ich die Frage nicht. Du willst einer Variablen vom Typ eines Interfaces den Typ einer Klasse übergeben, welche dieses Interface implementiert?

Nun ja, also genau das will ich tun, nur kommt eben das Interface als Class in die Methode geflogen, und ich weiß nicht, wie ich mir die implementierende Klasse scnappen kann, um mit newInstance() eine Instanz dieser Klasse zu erhalten, cool wäre es halt schon, wenn cih so eine Lokatormethode hätte, wo ich nur als Klasse ein Interface Iface.class übergeben müsste - eben der locate()-methode - und dann eine Instanz vom typ Iface bekäme, das ich dann auf IFaceImpl downcasten kann, also die Klasse, die das IFace implementiert. Und DAS sol gehen? Darf ich auch erfahren wie? Und vielen dnk auch für Deine Antwort mit den logischen Operatoren 🙂
 
Das Ganze kann nicht so einfach funktionieren, da es von einem Interface beliebig viele Implementierungen geben kann. Daher kann ein ServiceLocator nicht einfach die Implementierung liefern, sondern höchstens eine Liste aller Implementierungen.

Mögliche Ansätze sind hier:

Der Service Loader Mechanismus des JDK
https://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html

Der letzte mir bekannte Weg währe dann noch das classpath Scanning...
Oder du setzt auf ein Dependency Injection Framework wie Spring oder Guice.
 

Zurück
Oben