UFilter zum Finden von this-Methoden in Java (UFilter zum Finden von this-Methoden in Java), Lektion, Seite 723568
https://www.purl.org/stefan_ram/pub/ufilter_this_android (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
Java-Kurs

Ufilter zum Finden von this-Methoden in Java 

Dieser Ufilter gibt alle Methoden aus, die mit dem Zielobjekt »Main.this« aufgerufen werden können.

Der Methodenname wird einmal in geschweiften Klammern ausgegeben, um die Ausgabe sortieren zu können. Danach können diese Klammern gelöscht werden.

Fettgedruckte Programmteile müssen eventuell angepaßt werden.

(Fragment)
    try
{ final java.lang.reflect.Method[] methods = Main.class.getMethods();
final java.lang.StringBuilder builder = new java.lang.StringBuilder();
for( final java.lang.reflect.Method method : methods )
{ builder.setLength( 0 );
builder.append( method.getDeclaringClass() );
builder.append( " {" );
builder.append( method.getName());
builder.append( "} " );
builder.append( method.getReturnType().getName());
builder.append( " " );
builder.append( method.getName());
builder.append( "(" );
final java.lang.Class[] paramTypes = method.getParameterTypes();
boolean first = true;
for( final java.lang.Class c : paramTypes )
builder.append( ( first ?(( first = false )? null : " " ): ", " )+ c.getName() );
builder.append( first ? ")" : " )" );
java.lang.System.out.println( builder.toString() ); }}
catch( final java.lang.Exception exception ) {}

Ein „Ufilter“ ist ein Programm, das eine bestimmte Auswahl von Methoden oder Felder aus einer Bibliothek ausgibt.

(Notiz, basierend auf Ideen von Ralf Ullrich)

public final class Main implements java.lang.Runnable

{

public static void main( final java.lang.String[] args)

{ Util.withLoggerSetToOffDo( new Main() ); }

/* Dann habe ich die Klasse zum Finden des Archivs, die

Suchbedingungen und die Aktion für gefundenen Methoden aus der

Findeklasse abstrahiert, so daß sie jetzt im

Exemplarerzeugungsausdruck angegeben werden müssen. */

public void run()

{ new Finder

( "java.lang.Object",

new Filter0(),

new PrintConsumer<java.lang.reflect.Method>() ).

run(); }}

/* Ein Filter kann beispielsweise so aussehen: */

class Filter0 implements Filter

{

public boolean passed( final java.util.jar.JarEntry entry )

{ final java.lang.String name = entry.getName();

return

( name.endsWith( ".class" )) &&

! name.startsWith( "sun/" ) &&

! name.startsWith( "sunw/" ) &&

! name.startsWith( "com/sun/" ); }

public boolean passed( final java.lang.Class class_ )

{ return !class_.isAnonymousClass() &&

java.lang.reflect.Modifier.isPublic( class_.getModifiers() ); }

public boolean passed( final java.lang.reflect.Method method )

{ return

java.lang.reflect.Modifier.isPublic( method.getModifiers() ) &&

java.lang.reflect.Modifier.isStatic( method.getModifiers() ) &&

!java.lang.reflect.Modifier.isAbstract( method.getModifiers() )&&

method.getParameterTypes().length == 0 &&

method.getReturnType().isPrimitive() &&

method.getReturnType() != Void.TYPE; }}

/* Gefundene Methoden werden laut Main#run hiermit ausgegeben: */

class PrintConsumer<T>

implements Consumer<T>

{ public boolean consume( final T t )

{ java.lang.System.out.println( t ); return true; }}

/* Nun die eigentliche Finder-Klasse, die den Kern des

Programms darstellt: */

class Finder

{ static java.util.Set<java.lang.String> s;

final java.lang.String classPath;

final Filter filter;

final Consumer<java.lang.reflect.Method> methodConsumer;

public Finder

( final java.lang.String classPath,

final Filter filter,

final Consumer<java.lang.reflect.Method> methodConsumer )

{ s = new java.util.HashSet<java.lang.String>();

this.classPath = classPath.replace( '.', '/' ) + ".class";

this.filter = filter;

this.methodConsumer = methodConsumer; }

public void run(){ this.inspectJar(); }

public void inspectJar()

{ final java.net.URL url = java.lang.ClassLoader.getSystemResource

( this.classPath );

final java.net.JarURLConnection connection = Util.openConnection( url );

final java.util.jar.JarFile jarFile = Util.getJarFile( connection );

Util.iterate

( java.util.Collections.list( jarFile.entries() ), inspectEntry ); }

Consumer<java.util.jar.JarEntry> inspectEntry =

new Consumer<java.util.jar.JarEntry>()

{ public boolean consume( final java.util.jar.JarEntry entry )

{ final java.lang.String name = entry.getName();

if( Finder.this.filter.passed( entry ))

{ try

{ final String clzName = name.substring

( 0, name.length() - 6 ).replace( '/', '.' );

final Class class_ = Class.forName( clzName );

if( Finder.this.filter.passed( class_ ))

Util.iterate( class_.getDeclaredMethods(), inspectMethod ); }

catch( final java.lang.ClassNotFoundException classNotFoundException )

{ throw new java.lang.RuntimeException( classNotFoundException ); }}

return true; }};

Consumer<java.lang.reflect.Method> inspectMethod =

new Consumer<java.lang.reflect.Method>()

{ public boolean consume( final java.lang.reflect.Method method )

{ if( Finder.this.filter.passed( method ))

Finder.this.methodConsumer.consume( method );

return true; }}; }

/* Es fehlt noch die Schnittstelle für den Filter */

interface Filter

{ boolean passed( java.util.jar.JarEntry entry );

boolean passed( final java.lang.Class class_ );

boolean passed( java.lang.reflect.Method method ); }

/* Hier ist eine andere gelegentlich benutzte Schnittstelle: */

interface Consumer<T>{ boolean consume( T t ); }

/* Und die böse Klasse ohne jede Kohäsion: Util */

class Util

{ /* Die Verwendung von solchen Operationen wie »iterate«

ist hier fragwürdig. Was soll daran besser sein als »for«

direkt zu verwenden? Aber sie öffnet vielleicht den Weg

zu darauf aufbauenden Abstraktionen in späteren Versionen. */

public static <T> boolean iterate

( final T[] iterable, final Consumer<T> consumer )

{ for( final T t : iterable )

if( !consumer.consume( t )){ return false; }

return true; }

public static <T> boolean iterate

( final java.lang.Iterable<T> iterable, final Consumer<T> consumer )

{ for( final T t : iterable )

if( !consumer.consume( t )){ return false; }

return true; }

public static void withLoggerSetToOffDo( final java.lang.Runnable runnable )

{ final java.util.logging.Logger logger =

java.util.logging.Logger.getLogger( "" );

java.util.logging.Level old = logger.getLevel();

/* OK, das muß man auch nicht mit »for« formulieren. */

boolean looping = true; for

( logger.setLevel( java.util.logging.Level.OFF ); looping;

logger.setLevel( old ))

{ runnable.run(); looping = false; }}

/* Die beiden nächsten Methoden sollen nur Ausnahmen kapseln,

die sonst nicht durch bestimmte Schnittstellen gereicht werden

können. */

public static java.net.JarURLConnection openConnection

( final java.net.URL url )

{ try

{ return( java.net.JarURLConnection )url.openConnection(); }

catch( final java.io.IOException iOException )

{ throw new java.lang.RuntimeException( iOException ); }}

public static java.util.jar.JarFile getJarFile

( final java.net.JarURLConnection connection )

{ try

{ return connection.getJarFile(); }

catch( final java.io.IOException iOException )

{ throw new java.lang.RuntimeException( iOException ); }}}

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram723568 stefan_ram:723568 UFilter zum Finden von this-Methoden in Java Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd723568, slrprddef723568, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/ufilter_this_android