Reflection-fehlermeldung

  • Themenstarter Themenstarter looogi
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.
L

looogi

Gast
hallo habe folgende 2 Klassen. Ich möchte mit der Klasse TestR1 die Methoden von R3 aufrufen,

die werden zwar aufgerufen, doch ommt dann eine Fehlermeldung auf der Konsole... wieso?

Fehler lautet:

java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke

(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at TestR1.main(TestR1.java:17)
Caused by: java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:474)
... 5 more

Code:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class TestR1 {

	public static void main(String[] args) {

		try {
			Class c = Class.forName("R3");
			Object o = c.newInstance();

			Class clazz = o.getClass();
			Method[] methoden = clazz.getMethods();

			for (int i = 0; i < methoden.length; i++) {

				methoden[i].invoke(o, new Object[0]);
			}

		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}

	}

}

public class R3 {
		
		public void sagwas(){
			
			System.out.println("hallo von R3");
			
		}
        public void nochwas(){
			
			System.out.println("nochmal hallo");
			
		}
		
	}
 
Du bekommst nicht nur die Methoden von R3, sondern auch die von Object geerbten Methoden,
von denen verursacht wait() das Problem.
 
Mit "Method.getDeclaringClass()" solltest du rausfinden können, welche Methoden von Object und welche von deiner eigenen Klasse kommen.
(Vielleicht würde sich hier auch Annotationen anbieten, ein kleines Flag vor jeder Methode die aufgerufen werden soll.)
 
Beni hat gesagt.:
(Vielleicht würde sich hier auch Annotationen anbieten, ein kleines Flag vor jeder Methode die aufgerufen werden soll.)

Um das (IMO schönste Version) näher zu erläutern: Annotations gibts erst seit Java5. Das sähe dann so aus:
Code:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.annotation.*;

public class TestR1
{
   public static void main(String[] args)
   {
      try {
         Class c = Class.forName("R3");
         Object o = c.newInstance();

         Class clazz = o.getClass();
         Method[] methoden = clazz.getMethods();

         for (int i = 0; i < methoden.length; i++) {
            if (methoden[i].getAnnotation(Invoke.class) != null){
              methoden[i].invoke(o);
            }
         }
         
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

class R3
{
      @Invoke
      public void sagwas()
      {
         System.out.println("hallo von R3");
      }
      @Invoke
      public void nochwas()
      {
         System.out.println("nochmal hallo");
      }
}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface Invoke{}
 
..danke für die antworten...

..nur verstehe ich nicht was
Code:
 getAnnotation(Invoke.class)

dies hier macht?


danke
 
.

. ja und außerdem erkennt eclipse die Klasse Invoke nicht !!
🙁
 
um Annotation gehts doch die ganze Zeit, hast du die vorherigen Posts gelesen?
("ein kleines Flag vor jeder Methode die aufgerufen werden soll", wohl dieses "@Invoke")


komplett verstehen musst du das natürlich nicht,
wenn, dann erst nach dem lesen in entsprechenden Java-Bücher, das wird hier wohl kaum einer komplett wiederholen
(ich persönlich weiß davon nix 😉 )

wie gesagt gehts dabei um Java 5, nur in dieser hohen Version, die du wahrscheinlich nicht benutzt,
existieren Annotation und die Klasse Invoke
 
SlaterB hat gesagt.:
wie gesagt gehts dabei um Java 5, nur in dieser hohen Version, die du wahrscheinlich nicht benutzt,
existieren Annotation und die Klasse Invoke

Invoke ist eine Annotation (eine Art spezielles Interface), die Illuvatar in seinem Code definiert hat (die letzten Zeilen).
 
???:L du könntest auch einfach getDeclaredMethods() statt getMethods() benutzen, und alles funktinoiert
 
Roar hat gesagt.:
???:L du könntest auch einfach getDeclaredMethods() statt getMethods() benutzen, und alles funktinoiert
In diesem Fall würde das klappen. Allerdings liefert getDeclaredMethods eben alle deklarierten Methodem, unabhängig von ihrer Sichtbarkeit. Und wenn man dann aus einer anderen Klasse heraus eine "private" Methode aufrufen will, gibt es wieder eine Exception. Man müsste also noch entweder die Sichtbarkeit der Methode checken, oder mit java.lang.reflect.AccessibleObject die Sichtbarkeitsprüfungen aushebeln - was aber m.E. nur in absoluten Ausnahmefällen gerechtfertigt ist.
 
einfach alle methoden eines objekts aufzurufen ist auch nur in absoluten ausnahmefällen gerechtfertigt heh :bae:
 
Roar hat gesagt.:
einfach alle methoden eines objekts aufzurufen ist auch nur in absoluten ausnahmefällen gerechtfertigt heh :bae:
Zumindest kann ich mir nicht viele sinnvolle Anwendungsfälle vorstellen, stimmt schon. :wink:

Sollte es aber doch einmal notwendig sein, dann kann man mit AccessibleObject die Sichtbarkeitsprüfungen aushebeln (das kann z.B. für irgendwelche Serialisierungen sinnvoll sein), allerdings ist das eine Technik, die m.W. im J2EE-Bereich "verboten" ist.
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben