Klassen Dynamisches Casten?

Ich habe eine Datei mit möglicherweise mehrern Hundert Satzarten. Für jede Satzart gibt es eine Klasse zum Parsen. Ein Auswertprogramm soll nun die Möglichkeit bieten sich eine Satzart auszuwählen. Die anzuzeigenden Felder/Spalten können ebenfalls beim Aufruf bestimmt werden.
Ich will nun nicht für jeden Verarbeitungsschritt eine if-Abfrage machen sondern hoffe das eleganter hinzubekommen.
Ich stelle mir vor über ein switch (satzart) die Satzart-Klasse auszuwählen und einen "gemeinsamen" Namen zu verwenden. Bitte beachten: "gemeinsam" bedeutet nicht, dass verschiedene Objekte denselben Namen bekommen; es kann ein einem Ablauf nur eine Satzart selektiert werden also ist auch das Objekt eindeutig.

[Java]
switch (satzart) {
case 1: parser=new Satzart1(record); break;
case 2: parser=new Satzart2(record); break;
}

Iterator fname=brs.getIterator(0);
Iterator flength=brs.getIterator(2);
while (fname.hasNext()) { listLine.append(padLeft(parser.getField((String)fname.next()),Integer.parseInt((String)flength.next())));
}
System.out.println(listLine.toString());
[/Java]

So wie das hier aufgeschrieben ist funktioniert es leider aber nicht.
Man müsste parser als vom Typ Object oder einen anderen gemeinsame Super-Klasse der Satzarten definieren und dann irgendwie casten; mir fällt aber nicht ein wie.

mfg
Ulrich
 

Joew0815

Bekanntes Mitglied
Java:
public interface ISatzart
{
    ...
}

public class Satzart1 implements ISatzart
{
   ...
}

public class Satzart2 implements ISatzart
{
   ...
}

ISatzart parser;
switch (satzart) 
{
    case 1:  parser=new Satzart1(record); break;
    case 2:  parser=new Satzart2(record); break;
}

Alternativ würde auch eine Eltnerklasse gehen, von denen deine Satzarten erben.
 

Schandro

Top Contributor
Mach ein interface "Satzart" mit der methode zum parsen und einer Methode die die Bezeichnung zurückgibt. Dann speicherst du dir alle Klassen die "Satzart" implementieren per reflection in eine HashMap mit der Bezeichnung als key. Fertig.

PS: wobei du vermutlich besser den englischen Namen für "Satzart" benutzen solltest.
 
Zuletzt bearbeitet:
C

Conventions

Gast
Java:
public interface ISatzart
{
    ...
}

public class Satzart1 implements ISatzart
{
   ...
}

public class Satzart2 implements ISatzart
{
   ...
}

ISatzart parser;
switch (satzart) 
{
    case 1:  parser=new Satzart1(record); break;
    case 2:  parser=new Satzart2(record); break;
}

Alternativ würde auch eine Eltnerklasse gehen, von denen deine Satzarten erben.

Ich weis zwar nicht wie lange du bereits mit Java arbeitest oder aus welcher anderen Richtung du kommst, aber : "I" am Anfang eines Interface macht man in Java einfach nicht. Das kennt man eher aus Richtung C.
 

njans

Top Contributor
Sollte man nicht verwenden, aber fällt dir eine gute Benennung für Satzart ein? Satzartig? ^^
Generell sollte man in Java ja viel durch klare und clevere Benennung lösen, aber hier sehe ich keine.
Nebenbei wird in großen Firmen die prefix Notation verwendet, weil dies dann eben eindeutig ist.
 

njans

Top Contributor
Java:
 MyClass extends ParentClass

Weil MyClass von ParentClass erbt, ist ParentClass eben die Elternklasse von MyClass.
 
interface mit canParse() und parse()
dann einfach alle Parser aus einer ArrayList durchprobieren bis man einen passenden hat der sichn zuständig fühlt?
Im Prinzip sicher nicht schlecht. Aber das Eingabefile kann durchaus mehrer zig Gigabyte groß sein und damit ziemlich viele Sätze beinhalten. Wenn ich jedesmall hunderte von Möglichkeiten durchprobieren will wird das nicht sehr schnell. Letztlich macht doch die switch/case Schleife im Prinzip genau das.
 
Mach ein interface "Satzart" mit der methode zum parsen und einer Methode die die Bezeichnung zurückgibt. Dann speicherst du dir alle Klassen die "Satzart" implementieren per reflection in eine HashMap mit der Bezeichnung als key. Fertig.

PS: wobei du vermutlich besser den englischen Namen für "Satzart" benutzen solltest.
Mal sehen, ob ich das richtig verstanden habe. Mit "Bezeichnung" meinst Du den Namen der Satzart. Da ich die Satzart schon weiß braucht sie mir eigentlich keiner zurückzugeben. Ganz ehrlich, ich sehe nicht, was mir dieser Vorschlag an Verbesserung/Erleichterung gegenüber dem von Joew0815 bringt.
 
Java:
 MyClass extends ParentClass

Weil MyClass von ParentClass erbt, ist ParentClass eben die Elternklasse von MyClass.
Entschuldigung, war blöd von mir. Ich habe wirklich nach dem Schreibfehler "Eltnerklasse" gegoogelt. Aber ich denke mit der normalen Vererbung ist mir hier nicht gedient denn die Satzbeschreibung und die Aufbereitungsarten für die einzelnen Felder bleiben ja in der ChildKlasse. Und die müsste ich immer wieder explizit instanziieren, mit 256 Fallunterscheidungen (soviele mögliche Satzarten gibt es) und für jede gegebenenfalls hinzukommende weitere Methode wäre das auch wieder fällig. Der Sourcecode wäre einfach nicht mehr wartbar.
 

Schandro

Top Contributor
Mal sehen, ob ich das richtig verstanden habe. Mit "Bezeichnung" meinst Du den Namen der Satzart. Da ich die Satzart schon weiß braucht sie mir eigentlich keiner zurückzugeben. Ganz ehrlich, ich sehe nicht, was mir dieser Vorschlag an Verbesserung/Erleichterung gegenüber dem von Joew0815 bringt.
Wenn ich deinen ersten Post richtig verstanden habe gibt es mehrere hundert verschiedene Implementierungen. Wenn du Joew0815's Vorschlag umsetzt würde das ein switch mit mehreren hundert case's bedeuten die du immer wieder anpassen müsstest sobald eine neue Implementierung hinzugefügt wird. Bei meinem Vorschlag entfällt das komplett, er ist also um ein vielfaches sinnvoller falls ich deine Ausgangslange richtig verstanden habe.
 
Wenn ich deinen ersten Post richtig verstanden habe gibt es mehrere hundert verschiedene Implementierungen. Wenn du Joew0815's Vorschlag umsetzt würde das ein switch mit mehreren hundert case's bedeuten die du immer wieder anpassen müsstest sobald eine neue Implementierung hinzugefügt wird. Bei meinem Vorschlag entfällt das komplett, er ist also um ein vielfaches sinnvoller falls ich deine Ausgangslange richtig verstanden habe.
Ja, ich verstehe worauf du hinauswillst. Aber da die Satzart ein Integer zwischen 0 und 256 ist kann ich damit einen Array indizieren. Ich packe die Klassen also in einen Array und greife über die Satzart zu. Danke
 

fastjack

Top Contributor
Die angesprochenen Interfaces machen (aber ohne I und die ätzende { Einrückung, das ist nämlich nicht Java-Conventions). Außerdem Factoryklasse mit Cache machen (Map Nummer nach Satzart). Klassenname dynamisch zusammenbauen und mit Class.forName(...).newInstance() die gewünschte Satzart zu Nr XYZ instanziieren.
 
Die angesprochenen Interfaces machen (aber ohne I und die ätzende { Einrückung, das ist nämlich nicht Java-Conventions). Außerdem Factoryklasse mit Cache machen (Map Nummer nach Satzart). Klassenname dynamisch zusammenbauen und mit Class.forName(...).newInstance() die gewünschte Satzart zu Nr XYZ instanziieren.
Danke für die Anmerkungen. Von Konventionen lasse ich mich nur leiten wenn sie für mich einsichtig sind. Ein einfaches "Das tut man nicht" konnte ich als Kind schon nicht ausstehen. Ich finde das I als Anzeige, dass es sich um ein Interface handelt, eigentlich ganz praktisch und höre hier zum ersten Mal, dass es "verboten" sei. Bei den "}"-Einrückungen weiß ich nicht, welche Du meinst - meine oder die von Joew0815. Auch da muss ich sagen, gefallen mir meine zumindest besser als die anderen (wobei mein Beispiel etwas abartig geraten ist, weil ich es nicht mit CUT&PASTE eingefügt sondern direkt im Editor eingetippt; ich wollte ja nicht meinen Code hier posten sondern nur das Problem. Aber mein Einrückungen macht mein Eclipse auch standardmäßig so - als so ganz weg von den Konventionen kann das auch nicht sein.
Für die anderen Anmerkungen danke ich Dir (für die Kritik am Format natürlich ebenso) - aber ich verstehe den Vorteil gegenüber einem Array in der Art, wie ich es hier beschrieben habe nicht - ein Array mit 256 Feldern und direkt mit der Satzart indiziert "parser=array[satzart]". Ich werde mir das sicher mal näher anschauen - aber auf Anhieb leuchtet es mir jetzt noch nicht ein.
 

Schandro

Top Contributor
Von Konventionen lasse ich mich nur leiten wenn sie für mich einsichtig sind. Ein einfaches "Das tut man nicht" konnte ich als Kind schon nicht ausstehen.
Solange du alleine arbeitest ist das auch kein Problem, sobald du aber im Team arbeitest wirst du früher oder später auf die Java Code Convention umsteigen oder Probleme bekommen. Von daher solltest du es dir lieber gleich richtig angewöhnen. Am besten ist es immer noch ne gute IDE zu benutzen und den Sourcecode immer automatisch formatieren zu lassen.
 

njans

Top Contributor
Solange du alleine arbeitest ist das auch kein Problem, sobald du aber im Team arbeitest wirst du früher oder später auf die Java Code Convention umsteigen oder Probleme bekommen. Von daher solltest du es dir lieber gleich richtig angewöhnen. Am besten ist es immer noch ne gute IDE zu benutzen und den Sourcecode immer automatisch formatieren zu lassen.

Du hast vergessen zu sagen, dass es auch sinnvoll ist, wenn er hier Code postet ;)
Immerhin sollen wir es ja lesen.

Ich weiß nicht mehr, wer es geschrieben hat, aber jemand in diesem Forum hat als Antwort auf "die Conventions sind ja nur optional" clever geantwortet: "Die Deutsche Rechtschreibung ist auch nur optional".
 
S

Spacerat

Gast
Wozu eigentlich dieses switch?
Java:
interface RecordType {
  boolean canParse(Record r);
  void parse(Record r);
}

class Parser {
  private static final Collection<RecordType> recordTypes;

  static {
    Collection<RecordType> types = new ArrayList<RecordType>();
    //... Initialisierung der Satzarten (recordTypes)
    recordTypes = Collections.unmodifiableCollection(types);
  }

  static parse(Collection<Record> records) {
    for(Record r : records) {
      for(RecordType rt : recordTypes) {
        if(rt.canParse(r) {
          rt.parse(r);
          break;
        }
      }
    }
  }
}
Wenn du den ungeparsten Records nun noch einen Typ zuweisen kannst, kannst du dir die innere Schleife auch sparen. Diese würde sich dann etwa auf [c]r.getType().parse(r);[/c] reduzieren.
 
Zuletzt bearbeitet von einem Moderator:
Solange du alleine arbeitest ist das auch kein Problem, sobald du aber im Team arbeitest wirst du früher oder später auf die Java Code Convention umsteigen oder Probleme bekommen. Von daher solltest du es dir lieber gleich richtig angewöhnen. Am besten ist es immer noch ne gute IDE zu benutzen und den Sourcecode immer automatisch formatieren zu lassen.
Den Satz mit der Teamarbeit hatte ich selber schon formuliert - aber dann wieder entfernt. Natürlich ist es klar, dass man im Team Vereinbarungen treffen muss - und nicht nur da; im Prinzip hat ja jede Firma (wenn es einigermaßen professionell zugeht) Vorschriften wie Programm-Code zu gestalten ist. Dass es nicht ohne geht sehe ich ein und widerspricht auch nicht dem was ich angemerkt habe. Aber über das "I" als Kennzeichnung von Interfaces zu diskutieren, denke ich, schießt doch über das Ziel hinaus. Genau so etwas muss vereinbart werden - dem Einen gefällt es dem Anderen eher nicht. Ich habe einige grundlegende Bücher zu Java gelesen (z.B. "Learning Java", "Java Cookbook", "Java Swing"), da ist mir das "I" noch nie vorgekommen (mir fehlt natürlich noch die Praxis; es mag sein, wenn man mehr Programme geschrieben hat sieht man einiges anders). Und extra wegen dieser Diskussion jetzt habe ich mir mal die Java Conventions aus Code Conventions for the Java Programming Language: 9. Naming Conventions angeschaut. Zu Klassen steht da:
Code:
Class names should be nouns, in mixed case with the first letter of each internal word capitalized. Try to keep your class names simple and descriptive. Use whole words-avoid acronyms and abbreviations (unless the abbreviation is much more widely used than the long form, such as URL or HTML).
Und zu Interfaces finde ich:
Code:
Interface names should be capitalized like class names.

Also einen Verstoß gegen Konventionen kann ich gar nicht feststellen. Und nochmal - es macht es einfacher eine Kritik/Vorschrift anzunehmen wenn sie begründet ist. Ich will mich auch gar nicht über Eure Einlassungen beschweren - ich habe mich ja auch im letzten Posting sogar dafür bedankt -aber ohne Begründung muss ich alles selber einordenen. Frei nach Paulus: "Darum prüfet Alles und behaltet das Beste".
 
Du hast vergessen zu sagen, dass es auch sinnvoll ist, wenn er hier Code postet ;)
Immerhin sollen wir es ja lesen.

Ich weiß nicht mehr, wer es geschrieben hat, aber jemand in diesem Forum hat als Antwort auf "die Conventions sind ja nur optional" clever geantwortet: "Die Deutsche Rechtschreibung ist auch nur optional".
Ich habe Code hier eingestellt und er war lesbar; es fehlte nur ein Zeilenumbruch - und er wurde, glaube ich, von Allen einwandfrei verstanden; ich habe keine Nachfragen gehabt.
Bezüglich der Rechtschreibung muss ich mir auch nicht viel vorwerfen lassen - ich denke meine Texte sind ebenfalls ganz gut lesbar. Worauf es mir ankommt habe ich im letzten Posting hoffentlich verständlich zum Ausdruck gebracht. Zusammenfassend bin ich der Auffassung, dass der Zweck der Konventionen ist mir zu helfen mein Ziel zu erreichen. Wenn ich der Auffassung bin anders besser dorthin zu kommen muss ich abwägen ob die Abweichung gerechtfertigt ist. Bei dem "I" am Anfang des Interface-Namens fällt es mir leicht; eine Abweichung von der Großschreibung bei Klassen-Namen und Kleinschreibung von Variablennamen müsste in meinen Augen sehr gut begründet werden - denn das geht deutlich auf die Lesbarkeit des Programms.
Letztlich ist es doch so dass jedes sklavische Festhalten an Konventionen, egal wo, den Fortschritt behindert. Aber gegen Konventionen wird immer wieder verstoßen, sonst müsste nicht Duden regelmäßig eine neue Revision der Rechtschreibvorschriften herausbringen.
 
B

...ButAlive

Gast
"I" vor Interfaces ist meiner Meinung nach ein Relikt aus der Zeit als IDEs nur ein Texteditor mit Build-Button waren. Da war es interessant gleich am Namen zu sehen, dass es ein Interface ist. Heute bekommt man von jeder IDE gleich einen Fehler gemeldet wenn man
Code:
new MyInterface();
schreibt und muss nicht warten bis ein Build durch ist.

Wenn man heute noch das "I" vor ein Interface hat man ein anderes Problem; man möchte Namenskonflikte zwischen Interface und Implementierung vermeiden. Das braucht man aber nicht, das Interface beschreibt etwas abstraktes, die Implementierung etwas kongretes, dafür sollte es einfach sein zwei unterschiedliche Namen zu finden.

Falls nicht: Wenn man etwas keinen Namen geben kann, hat man das Problem noch nicht verstanden (ich glaube das ist aus "Clean Code").
 
G

gazzzzt

Gast
Wenn man im Elfenbeinturm sitzt und und den lieben langen Tag Zeit hat, kann man natürlich wunderbare akademische Debatten über die Hölle der I-Notation und die reine Lehre führen. In realen Projekten sieht die Welt aber schon ein wenig anders aus. Da ist es durchaus ein pragmatischer Ansatz, seinen Quelltext eben nicht mit allerlei Rauschen wie AbstractIrgendwas, DefaultIrgendwas und IrgendwasImpl aufzublähen, sondern wenn es passt einfach auf ein kurzes knackiges Schema wie IIrgendwas und Irgendwas zurückzugreifen um Verhalten/Abstraktion und Implementierung zu trennen. Zumal das Ganze hier endgültg lächerlich wird, wenn ein paar Foristen mal eben einem Großteil der an Eclipse- und Apache-Projekten beteiligten Entwickler völlige Unkenntnis attestieren. Man hat ja schließlich schon mal im Clean Code geblättert und kann nun wunderbar mitreden.
 
S

Spacerat

Gast
[OT]Entschuldigt mal Kollegen...
Ist es sinnvoll sich blos über irgendwelche Conventions zu unterhalten, als an einer Lösung zu feilen? Ehrlich gesagt geht mir dieses herum gereite auf Konventionen auch tierisch auf den S...., denn es ist nicht hilfreich! Wenn ihr geposteten Code nicht versteht, weil er keinen Konventionen entspricht, habt ihr halt selber schuld. Da seht ihr mal, wie weit ihr mit euren Konventionen kommt. Programmiert ihr Java oder Javakonventionen? Beschränkt dieses ewige gemecker doch auf Code, wo man wirklich Bauchschmerzen bekommt. Ein wenig analytischer Verstand sollte bei Entwicklern schon Vorrausetzung sein.[/OT]
 
Zuletzt bearbeitet von einem Moderator:
Wozu eigentlich dieses switch?
Wenn du den ungeparsten Records nun noch einen Typ zuweisen kannst, kannst du dir die innere Schleife auch sparen. Diese würde sich dann etwa auf [c]r.getType().parse(r);[/c] reduzieren.
Danke. Von dem
Code:
switch
bin ich ja schon weg -das war nur ein Ansatz um in wenigen Zeilen meine Frage deutlich zu machen.
Im Augenblick würde ich es wohl so machen:
[Java]
public interface IParser {
public void runParser(Parser record);
public String getField(String fieldname);
public String getField(String fieldname, String format);
}

public class ParserCollection {
IParser[] ip = new IParser[256];
public ParserCollection() {
ip[30] = new Record30_parser();
}

public IParser getParser(int i) {
return ip;
}
}

public class Report {
ParserCollection pc;
BuildReportSeclections brs;
public Report(File file) throws Exception {
pc = new ParserCollection();
brs=new BuildReportSeclections();
....
}

public void addNewRecord(Record record) {
smfparser = pc.getParser(brs.getRectypes()[0]);
smfparser.runParser(record);

Iterator fname=brs.getIterator(0);
Iterator flength=brs.getIterator(2);

while (fname.hasNext()) {
listLine.append(padLeft(smfparser.getField((String)fname.next()),Integer.parseInt((String)flength.next())));
}
Say.message(listLine.toString());
}


[/Java]

Beispielhaft habe ich in ParserCollection nur einen Satzparser instantiiert; hier werde ich aber wohl alle Satzarten durchdeklinieren müssen - ich muss sie ja namentlich aufrufen.
 
S

Spacerat

Gast
@Schandro: Reflection ist ein Zeichen von Mangel an Ideen, es ohne zu lösen. Das durfte ich mir auch schon oft genug anhören. Jede Wette, du reichst ihn bei Zeiten wie ein altes Familienerbstück an den nächsten weiter.
Andererseits... Okay... Reflection.
So kann man die RecordTypes nämlich in einer Schleife instanzieren.
Java:
for(int n = 0; n < 256; n++) {
  ip[n] = Class.forName("Record" + n + "_parser").newInstance();
}

Woran erkennt man beim Laden der Sätze überhaupt um welchen Satztyp es sich handelt? Etwa an dem int bei [c]getParser()[/c]? Das int steht dann möglicherweise in der Datei mit den Sätzen und die Datei wird evtl. per InputStream gelesen. Schon kann man dem Record selbst eine Instanz von RecordType übergeben oder gar den Record gleich parsen lassen.
 
Zuletzt bearbeitet von einem Moderator:

Schandro

Top Contributor
@Schandro: Reflection ist ein Zeichen von Mangel an Ideen, es ohne zu lösen. Das durfte ich mir auch schon oft genug anhören. Jede Wette, du reichst ihn bei Zeiten wie ein altes Familienerbstück an den nächsten weiter.
Ich weiss ja nicht was die konkrete Anforderungen an das Programm sind, aber es sieht so aus als wären dutzende verschiedene Klassen benötigt die dynamisch aufgerufen werden sollen. Imho geht das nur sinnvoll mit Reflection, du kannst mir aber auch gerne das Gegenteil beweisen :bae:

Wenn die Anforderungen anders wären, bspw. das man die Implementierungen nicht unbedingt auch als Klasse benötigt, dann würde ich natürlich nicht zu Reflection raten.
 
S

Spacerat

Gast
Imho geht das nur sinnvoll mit Reflection, du kannst mir aber auch gerne das Gegenteil beweisen :bae:
ServiceProviderInterface. ;)
Hoffe das Stichwort genügt. Jetzt einen Beweis dafür anbringen, dass es damit funktioniert, würde nicht nur den Rahmen des Threads sprengen sondern auch dessen Anforderungen (ein simpler Methodenaufruf eines Interfaces).
[EDIT]Wieso sollte ich das eigentlich beweisen? SPInn ich denn? :lol:[/EDIT]
 
Zuletzt bearbeitet von einem Moderator:
B

...ButAlive

Gast
Ach wir triften schon wieder vom Thema ab... Vom Elfenbeinturm gesehen, ist das eigentliche Problem, dass wir nicht wissen wie die Daten aussehen. Vielleicht lässt sich ein Satz einfach doch
Code:
String#split(...);
teilen, und die eigentliche Aufgabe ist, jedem Teil einen Namen zu geben. Da bräuchte man keine 100 Parserklassen und die Diskussion über "I" vor Interfaces, oder Reflectiontions würden sich erledigen, eine Map mit der Zuorndnung könnte es tun.

Sollte die Struktur der Eingabe komplexer sein, und Ulrich Schmidt die Daten auch selbst erstellen, könnte die Empfehlung Richtung Datenbank gehen.

Mehrere hundert Satzarten und pro Satzart eine Parserklasse klingt nach dem eigentlichen Problem, wie man diese verwalten könnte ist nur die logische Folgerung daraus.

Solange nicht bekannt ist, wie so ein Satz beispielsweiße aussieht, kann man hier nur Symthome bekämpfen. Um eine elegante Lösung zu finden müssen die Eingabedaten bekannt sein.

[OT]
@gazzzzt Ich bin weit entfernt vom Elfenbeinturm, täglich ärger ich mich über so nichtssagende Namen wie IIrgenwas und die passende Implementierung Irgendwas und muss im Code nachschauen, was die Intension des Autors sein könnte.

Apache und Eclipse sind meiner Meinung nach keine guten Beispiele für guten Code. Schau dir guava, guice und Spring an, das ist sexy Code.
[/OT]
 
S

Spacerat

Gast
[OT]
Apache und Eclipse sind meiner Meinung nach keine guten Beispiele für guten Code. Schau dir guava, guice und Spring an, das ist sexy Code.
Ohoh... Du weisst schon, das Apache und Eclipse mächtig grosse Felsen im Gegensatz zu den von dir genannten Kieselsteinen sind? Nö, ich (zumindest) schau's mir besser nicht an, da es sich bei jedem dieser Frameworks um auf Java aufgesetzte handelt. Besserer Quellcode ist nicht gleichbedeutend mit besseren Anwendungen und um bessere Anwendungen zu entwickeln, bedarf es keinem Möchtegern-Framework, nur weil dessen Quellcode evtl. besser aussieht (Murks kann man auch dort verzapfen). Ausserdem sind GUICE und Spring afaik sogar Teil des gesamten Apache-Frameworks (Camel)
Letztendlich ist es eigentlich auch egal, wie Quellcode genau aussieht oder gegen welche Konventionen er "verstösst". Solange er nachvollziebar bleibt, ist alles in Ordnung. Das gilt im übrigen nicht nur für Java. Deswegen kann man sich Aussagen wie "Das tut man in Java aber nicht" eigentlich auch stets sparen, erst recht, wenn es um hoch heilige Namenskonventionen geht.[/OT]
 
Zuletzt bearbeitet von einem Moderator:
Ich weiss ja nicht was die konkrete Anforderungen an das Programm sind, aber es sieht so aus als wären dutzende verschiedene Klassen benötigt die dynamisch aufgerufen werden sollen. Imho geht das nur sinnvoll mit Reflection, du kannst mir aber auch gerne das Gegenteil beweisen :bae:

Wenn die Anforderungen anders wären, bspw. das man die Implementierungen nicht unbedingt auch als Klasse benötigt, dann würde ich natürlich nicht zu Reflection raten.
Da der Thread bis hierher gediehen ist, ist es vielleicht fair die Anforderungen zu beschreiben.
Mein Programm soll die SMF-Sätze eines z/OS-Systems auswerten. Jede Satzart wird durch ein Byte im Record dargestellt - dadurch sind maximal 256 Satzarten möglich. Die werden nicht alle immer genutzt, müssen aber vorgesehen werden. Die Sätze sind sehr variabel lang, 50KB und mehr sind durchaus möglich. Die Records sind in Sections untergliedert, jede Section hat ein eigenes Mapping. Die Lage, Länge und Anzahl Häufigkeit des Auftretens dieser Sections wird in einem Index am Beginn des Records beschrieben. Im Report werden aber immer nur einige Felder benötigt; geparsed wird also nicht der gesamte Record sondern nur die interessierenden Sections. Das heißt mit anderen Worten auch, jede Satzart kann hunderte von Feldern beschreiben und macht auch die Aufbereitung - von binär, von headezimal, von gepackt dezimal usw in eine lesbare Form.
Da die Satzarten so mächtig sind habe ich sie auch nicht selber editiert sondern mit einem anderen Java-Programm generiert; das liest die Assembler-Macro-Umwandlung der Satztyps und baut daraus automatisch den Satzart-Parser.
Wenn ich diese Parser jetzt alle systematisch benenne dann könnte der Code zum Erstellen des Array so aussehen:
[Java]
public class ParserCollection {
IParser[] ip = new IParser[256];
public ParserCollection() {
for (int i=0; i< 256;i++) {
Class cls = Class.forName("myClassName"+i);
ip = (IParser)cls.newInstance();
}

public IParser getParser(int i) {
return ip;
}
}
[/Java]
 
ServiceProviderInterface. ;)
Hoffe das Stichwort genügt. Jetzt einen Beweis dafür anbringen, dass es damit funktioniert, würde nicht nur den Rahmen des Threads sprengen sondern auch dessen Anforderungen (ein simpler Methodenaufruf eines Interfaces).
Das hat natürlich den Nachteil, dass ich doch wieder alle Klassennamen explizit editieren muss; und ich muss in meinem Fall höllisch aufpassen, dass die Reihenfolge in dem provider-configuration-file immer stimmt, sonst bekommt die Klasse plötzlich eine falsche Nummer. Das Thema mit einem Configuration-File ist für mich noch nicht ganz vom Tisch, wenn ich die Klasse einer Satzart möglicherweise nochmal splitten muss und ich aus irgendeinem Grunde keine Systematik zum dynamischen Aufbau der Tabelle mache. In dem Fall kommt die HashTable von Schandro zum Einsatz. Dann würde das File aber eine Tabelle mit zwei Spalten haben müssen; der Klasse und einem Bezeichner dafür.
 
S

Spacerat

Gast
Und was macht das im Hintergrund? Reflection :) Es geht auch damit nicht ohne.
Sehr witzig. Wenn man die Teile des gesamten APIs, die nicht zu empfehlende Programmiertechniken verwenden, auch noch zu den nicht empfehlenswerten hinzuzählt, dürfte man die ganze Standard-API nicht mehr empfehlen. Ich bin mir ja nicht mal sicher, ob [c]<Class>.forName("anything").newInstance()[/c] schon als Reflection angesehen werden kann, weil Class immernoch 'ne Standardklasse ist. Ich hab' mich ja auch bereits dazu überreden lassen, SPI war halt doch nicht so sinnvoll, wie von Schandro "gefordert", weil... ach was solls, der TO scheints ja zu kennen.

@Ullrich Schmidt: Wieso machst du aus den beiden Anwendungen nicht eine einzige mit eine ParserGeneratorClass welche dir eine ArrayList der Parser liefert. Gleich nach dem Erstellen der Typ-Klasse vom Assembler-Makro fügst du ein Objekt dieser Klasse in die Liste ein und kannst so die Records nacheinander gleich beim Lesen der Datei parsen. Eine HashMap benötigst du jedenfalls nicht, das ID-Byte sollte als Key bzw. Index in die ArrayList genügen.
Ich hab' aus purem Interesse mal nach diesem SMF-Format gesucht. Leider findet sich dafür nirgendwo eine Beschreibung über den Aufbau einer solchen Datei (sofern es überhaupt eine ist und nicht blos 'ne organisierte Ansammlung von Blöcken auf der Platte des Dateisystems). Hast du irgendwo so eine Beschreibung?
 
@Ullrich Schmidt: Wieso machst du aus den beiden Anwendungen nicht eine einzige mit eine ParserGeneratorClass welche dir eine ArrayList der Parser liefert. Gleich nach dem Erstellen der Typ-Klasse vom Assembler-Makro fügst du ein Objekt dieser Klasse in die Liste ein und kannst so die Records nacheinander gleich beim Lesen der Datei parsen. Eine HashMap benötigst du jedenfalls nicht, das ID-Byte sollte als Key bzw. Index in die ArrayList genügen.
Ich hab' aus purem Interesse mal nach diesem SMF-Format gesucht. Leider findet sich dafür nirgendwo eine Beschreibung über den Aufbau einer solchen Datei (sofern es überhaupt eine ist und nicht blos 'ne organisierte Ansammlung von Blöcken auf der Platte des Dateisystems). Hast du irgendwo so eine Beschreibung?
Eine Beschreibung findest Du zum Beispiel in http://publibz.boulder.ibm.com/epubs/pdf/iea2g2c1.pdf
Du solltest nicht alle anderen für blöd halten; die Attitüde mit der Du meine Beschreibung des Formats wegwischst ist schon eher nicht freundlich.
Mit dem Erzeugen des Codes habe ich mir ein Werkzeug geschaffen mit dem ich die Daten verarbeiten kann. Die SMF-Sätze liegen als Flatfile vor mit allen möglichen Informationen über das was auf dem System los war - das Ganze geht so in Richtung BI. Die Sätze eignen sich zur Kapazitätsplanung, zum Auditieren, fürs Accounting und vielem mehr. Meine Anwendung soll als Backend dem Anfrager bestimmte Felder aus diesem Repository zurückgeben. Das ist sehr vergleichbar mit einer Datenbankabfrage. Ich habe mir die Aufgabe selber erst mal so gestellt. Es kann aber auch vernünftig werden die Informationen in eine Datenbank zu überführen; ob sich dieser Aufwand lohnen würde muss die Zeit zeigen. Aber da ist ja auch nichts verloren; parsen muss ich die Daten so oder so.
 
S

Spacerat

Gast
Du solltest nicht alle anderen für blöd halten; die Attitüde mit der Du meine Beschreibung des Formats wegwischst ist schon eher nicht freundlich.
:oops: Ist mir nicht aufgefallen. Nach der genauen Beschreibung fragte ich nur aus eigenem Interesse (Datentyperkennung; Eines meiner Projekte), danke für den Link.
Für eine Lösung hier genügt die Info, dass Satztypen nur durch ein Byte definiert werden und daraus folgte der Schluss, dass eine Liste bzw. ein Array anstatt einer Map völlig ausreicht.
Ich denke mal, dass Schandro inzwischen auch von der Map weg ist, seit er deinen Code gesehen hat und die Sache mit der Byte-ID kennt.
[OT]Für blöd' - wenn auch nicht für grundsätzlich - halte ich nur jene, die seit X Beiträgen nichts anderes zu tun haben, als auf ihren geheiligten Konventionen herumzureiten oder mit rhetorischen Frage und Antwortspielen Lösungsansätze in Frage zu stellen, ohne sich selbst an einer solchen zu beteiligen. Das Schlimme daran: Mindestens einer von denen ist auch noch IRC-Operator und/oder Moderator.[/OT]
 
Nochmal Danke an Alle die mir hier mit Rat geholfen haben. Es war eigentlich alles hilfreich auch wenn die Diskussion einige seltsame Wendungen genommen hat. Aber ich denke das Thema ist jetzt wirklich ausgelutscht.
RIP :cry:
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Dynamisches Casten mal wieder Java Basics - Anfänger-Themen 4
A Dynamisches casten Java Basics - Anfänger-Themen 19
B Generische Typen für dynamisches Formular Java Basics - Anfänger-Themen 3
J Dynamisches Array durch split()-Funktion? Java Basics - Anfänger-Themen 3
N Dynamisches Programmieren/Fibonacci Java Basics - Anfänger-Themen 1
J Polymorphie und Dynamisches Binden richtig nutzen Java Basics - Anfänger-Themen 11
O Schlange als dynamisches Feld - Aufwand Java Basics - Anfänger-Themen 16
S Klassen Objekt- Tabelle / Dynamisches 2Dimensionales Array für Objekte Java Basics - Anfänger-Themen 6
C Erste Schritte Dynamisches Array Java Basics - Anfänger-Themen 11
T Dynamisches abarbeiten von statischen Methode aus verschiedenen Klassen. Java Basics - Anfänger-Themen 5
X Methoden [GWT] Dynamisches Textfeld PopUp erstellen Java Basics - Anfänger-Themen 6
L dynamisches erzeugen von array Listen Java Basics - Anfänger-Themen 7
R dynamisches zweidimensionales Feld erzeugen Java Basics - Anfänger-Themen 8
A dynamisches Array - Index Liste Java Basics - Anfänger-Themen 2
maddin86 3 Dateien gleichzeitig speichern in dynamisches Benutzerverzeichnis (Windows) Java Basics - Anfänger-Themen 4
A dynamisches Array simulieren Java Basics - Anfänger-Themen 8
M Dynamisches und statisches binden Java Basics - Anfänger-Themen 17
M Dynamisches Binden Java Basics - Anfänger-Themen 8
M dynamisches Clipboard mit Buttons Java Basics - Anfänger-Themen 5
J Dynamisches/Statisches Binden ?? Java Basics - Anfänger-Themen 5
R dynamisches binden Java Basics - Anfänger-Themen 3
K dynamisches Array Java Basics - Anfänger-Themen 13
M Zweidimensionales dynamisches Array füllen Java Basics - Anfänger-Themen 2
Bernasconi dynamisches JDialog Java Basics - Anfänger-Themen 2
R Dynamisches Gegenerieren von Objekten Java Basics - Anfänger-Themen 25
P dynamisches Binden klappt nicht so recht Java Basics - Anfänger-Themen 7
S dynamisches array + konstruktor Java Basics - Anfänger-Themen 5
K dynamisches Array erzeugen Java Basics - Anfänger-Themen 5
tom.j85 TicTacToe - probleme beim Casten Java Basics - Anfänger-Themen 6
B Datentypen Welcher Typ wird beim Casten übernommen? Java Basics - Anfänger-Themen 12
G Probleme beim casten von double zu int Java Basics - Anfänger-Themen 3
BuTTerBroTHDx Char Wert in int casten ? Java Basics - Anfänger-Themen 4
A Vererbung Mit Casten direkt auf Sub-Klasse Zugreiffen Java Basics - Anfänger-Themen 6
N Variablen zurück casten Java Basics - Anfänger-Themen 3
F Casten bei Implements Java Basics - Anfänger-Themen 2
S Klassen casten, IS-A Beziehung Java Basics - Anfänger-Themen 5
J Generics casten Java Basics - Anfänger-Themen 14
T Probleme beim casten Java Basics - Anfänger-Themen 9
M Casten Java Basics - Anfänger-Themen 2
K Collections Vector zu String casten Java Basics - Anfänger-Themen 4
S Polymorphes Objekt in eigentliche Klasse casten Java Basics - Anfänger-Themen 6
masii Methoden Parameter casten? Java Basics - Anfänger-Themen 2
D Datentypen Abstrakter Datentyp lässt sich nicht casten Java Basics - Anfänger-Themen 7
U ArrayList casten Java Basics - Anfänger-Themen 37
F g.drawLine in g 2D casten Java Basics - Anfänger-Themen 5
A Klassen ArrayList richtig / sicher Casten? Java Basics - Anfänger-Themen 3
J Frage zu generischer Klasse und Casten Java Basics - Anfänger-Themen 14
M Frage zum Casten von Objekten Java Basics - Anfänger-Themen 5
M sicheres/unsicheres Casten bei Objekten Java Basics - Anfänger-Themen 13
D Object auf JTextpane / jTextArea casten? Java Basics - Anfänger-Themen 3
B Casten oder vielleicht was anderes? Java Basics - Anfänger-Themen 9
T Boolean in ein Objektdatentyp casten möglich? Java Basics - Anfänger-Themen 5
J Casten (Typumwandlung) Java Basics - Anfänger-Themen 12
P Casten Hash Map Java Basics - Anfänger-Themen 4
W Auf 'this' casten Java Basics - Anfänger-Themen 3
M casten Java Basics - Anfänger-Themen 11
D Casten eines Objekts: Funktion der Oberklasse aufrufen Java Basics - Anfänger-Themen 4
G Datentypen char to int casten - falsches Ergebnis! Java Basics - Anfänger-Themen 6
S casten array in int von float Java Basics - Anfänger-Themen 5
C Probleme beim casten und Objekt zugriff Java Basics - Anfänger-Themen 12
P Klasse nach Element casten Java Basics - Anfänger-Themen 4
G Double casten Java Basics - Anfänger-Themen 8
O Object nach Double casten Java Basics - Anfänger-Themen 11
L Object[] in String[] casten Java Basics - Anfänger-Themen 7
V Gelesene FTP Datei richtig casten Java Basics - Anfänger-Themen 9
T Properties casten Java Basics - Anfänger-Themen 4
G Arrays casten? Java Basics - Anfänger-Themen 12
G string "null" in null casten Java Basics - Anfänger-Themen 3
M casten und Generics Java Basics - Anfänger-Themen 9
S Objekt Casten Java Basics - Anfänger-Themen 4
G String nach int casten Java Basics - Anfänger-Themen 5
G Vektor auslesen und als int Variable casten Java Basics - Anfänger-Themen 4
G String in Date casten. Java Basics - Anfänger-Themen 7
G String in Date casten Java Basics - Anfänger-Themen 4
G String in Long casten Java Basics - Anfänger-Themen 2
G Object[] [] nach vector casten. Java Basics - Anfänger-Themen 3
G printStackTrace(); in String casten Java Basics - Anfänger-Themen 3
G String in int casten Java Basics - Anfänger-Themen 2
G Integer[] nach int[] casten - wie? Java Basics - Anfänger-Themen 2
D Arrays casten Java Basics - Anfänger-Themen 12
G Casten ? Java Basics - Anfänger-Themen 3
HaukeG Casten to String und Vergleichen Java Basics - Anfänger-Themen 2
G ich komm nicht weiter -> String in int casten Java Basics - Anfänger-Themen 4
T Casten von Choice auf Vector oder Object[] Java Basics - Anfänger-Themen 14
B Vector nach float[] casten Java Basics - Anfänger-Themen 6
G String zu byte[] "casten"? Java Basics - Anfänger-Themen 3
M Hin und Her Casten Object->int und int->Object Java Basics - Anfänger-Themen 3
T Typsicheres casten eines Objects Java Basics - Anfänger-Themen 5
D Object[] in Liste casten? Java Basics - Anfänger-Themen 8
T Chaosprogrammierer hat einen fehler beim casten? Java Basics - Anfänger-Themen 5
J Attribut casten Java Basics - Anfänger-Themen 3
A Array mit generischen Typen casten? Java Basics - Anfänger-Themen 6
C Automatisches Casten => inkompatibel Java Basics - Anfänger-Themen 7
G Byte-Code einlesen und zu Hex casten Java Basics - Anfänger-Themen 2
T Object[] zu String[] casten? Java Basics - Anfänger-Themen 3
R Double nach Integer casten Java Basics - Anfänger-Themen 8
L Adresse in String[] casten Java Basics - Anfänger-Themen 6
M Object auf Interface casten? Geht das? Java Basics - Anfänger-Themen 21
U ArrayLists und Casten Java Basics - Anfänger-Themen 2
O TreeMap nach Object[] casten? Java Basics - Anfänger-Themen 3

Ähnliche Java Themen

Neue Themen


Oben