Hat der Compiler einen Fehler oder warumbeendet return nicht eine Methode ?

ernst

Top Contributor
Hallo allerseits,
In der folgenden Methode unten wird nach return _nicht_ die Methlode verlassen, sondern an der Stelle (XXX)
weitergemacht. Kann das sein ??
ich dachte, dass mit return sofort die Methode verlassen wird.

mfg
Ernie



Java:
    public void renameTree(File node) throws Throwable{
        int i;
        boolean erg;
        String umbenennungString;
        File[] files=null;
        String throwString;
        MyException myEx; 
     
        try{
            // Achtung: wenn node kein Directory dann null als Ergebnis
            files = node.listFiles();
            if(files==null){
                System.out.println("Hallo");       // mit F4 an diese Stelle geesprungen
            }
        }
        catch (Throwable t){
            //melde ="\nF E H L E R - M E L D U N G :  Lesebzugriff nicht erlaubt von:\n"+node;
            throwString="\nF E H L E R - M E L D U N G :  Lesebzugriff nicht erlaubt von:\n"+node;            
            System.out.println("\n"+throwString);                        
            throw t;
        }

        try{
            if (isLeaf(node)) {
                //System.out.println("rename "+node.getName());
                renameNode(node);
                return;               // die Methode wird nicht beendet. Warum?? Sondern es wird bei (XXX) weitergemacht
            }
            else{
                for (i = 0; i < files.length; i++) {                    // (XXX) hier wird weitergemacht !!!
                    //System.out.println("rename "+files[i].getName());                    
                    renameTree(files[i]);
                }
                //System.out.println("rename "+node.getName());                                    
                renameNode(node);            
            }
        } 
        catch (Throwable t){
            if(t instanceof MyException){
                if ( ((MyException) t).sofortAbbruch == false){
                    myMeldung.append(((MyException) t).throwMeldung);
                }
            }
            else{
                System.out.println("Meldung in renameMenue(): "+t.getMessage()+"\n");  
                myMeldung.append("\n"+t.getMessage());    
                t.printStackTrace();       
                throw t;                
            }
        }
    }
 
Moin,
wenn
if (isLeaf(node)) wahr ist, dann wird Folgendes durchgeführt:
renameNode(node);
return;
und danach wird mit der FOR-Schleife im else-Fall weitergemacht??
Sehr unwahrscheinlich 😱

Entweder passt der gepostete Code nicht oder du läufst nicht da durch, wo Du glaubst zu sein !
Wie sehen denn die Methoden "isLeaf" und "renameNode" aus ??

VG Klaus
 
Hier das gesamte Programm.
Du kannst´jaa an die Stelle mit der Ausgabe "Hallo" springen und beobachten wie es weitergeht.

mfg
ernst


Java:
package renamedirectory_10;


/*
P R O G R A M M B E S C H R E I B U N G
Windows läßt zu, dass ein Anwender zwar eine Verzeichnistiefe
anlegen kann, so dass der Verzeichnispfad über 255 Zeichen groß wird.
Allerdings kann mam dieses Verzeichnis dann nicht mehr mit dem
Explorer löschen.
Deshalb benennt dieses Programm alle Unterverzeichnisse in
Verezeichnisse mit möglichst Namenslänge um.

I)
Das explizite Vergeben von Schreibrechten bei der Umbennenung funktioniert nicht. 
Trotzdem soll dies nicht zum Programmabbruch führen:
Es wird nur eine entsprechende Meldung erscheinen.
Trotzdem klappt die Umbennenung in den meisten Fällen.
Komischerweise gibt es keinen Fehler wenn die Umbennenung nicht klappt.
Warum ?



Bemerkung:
Mit setWriteable(...) kann man theoretisch Berechtigungen für Schreibzugriffe
vergeben. Dies funktioniert leider aber nicht in der Praxis.
Man muß die Eigenschaft "schreibgeschützt" in Win 10 auf den obersten Ordner
zurücksetzen, nachdem dieses Programm gestartet wurde.
Dann kann der ganze Verzeichnisbaum im Explorer von Win 10 gelöscht werden.


Wie entfernt man einen Verzeichnisbaums ?
- Dieses Programm starten
- Eigenschaft "schreibgeschützt" im Explorer auf den obersten Ordner entfernen.
- Löschen des obersten Knotens des Verzeichnisbaums.


Was fehlt noch:
- Bitte warten soll gleich erscheinen, nicht erst amEnde des Programms

II)
1)
In 
renameMenue(ae,myMeldung)
muss auf das JTextArea-Feld zugegriffen werden.
Deswegen wird dieses JTextArea-Feld als Parameter myMeldung übergeben.
Wenn man dies nicht machen würde und den Aufruf
renameMenue(ae)
so konstruieren würde, müßte man aus dem Ereignis ae die Information 
entnehmen, wo sich die Stelle befindet, wo die Zeichenfläche JPanel 
angebracht wurde:
Container con = ((JButton) (ae.getSource())).getParent();



 */
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;

public class Startklasse {

    public static void main(String[] args) {
        MyFenster myF = new MyFenster();
        //  Programm wird beendet (aus dem Arbeitsspeicher entfernt), wenn Fenster weggeklickt
        //  wird. Nachprüfen mit Task-Manager
        myF.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }
}

    
  
    
    // Konstruktor
class MyFenster extends JFrame {
    // Stelle in MyFenster deklarieren, an die montiert wird.
    private Container myCont;
    // Eine Zeichenfläche deklarieren
    private JPanel myPan;
    private JButton myRenameButton;
    private JTextArea myMeldung;    
    private JScrollPane sp;     
    private JLabel myMeldungenLabel;

    // Eine Wanze deklarieren
    private MyWanze myWanze;
    private GridBagLayout myGBL_10_1;    

    
    
    
    // Konstruktor
    public MyFenster() {
        String meldung;
        // Liefert die Stelle in MyFenster, an die montiert wird.
        myCont = getContentPane();
        // Erzeugt eine Zeichenfläche
        myPan = new JPanel();
        // Erzeugt Buttons
        myRenameButton = new JButton("Start");
        meldung="Umbenennen eines ganzen Verzeichnisbaums einschließlich der Dateien\n";
        meldung = meldung+"Dieses Umbenennungsprogramm ist rekursiv und hat deshalb eine schlechetere Performance.";
        
        myMeldungenLabel = new JLabel("Meldungen des Programms:");
        myMeldung = new JTextArea(meldung);
        // JTextArea scrollbar machen. Wichtig bei vielen Fehlermeldungen
        sp = new JScrollPane(myMeldung);             

        // Alternative Möglichkeit myMeldung anzufügen
        // sp.setViewportView(myMeldung);        
        
        // vertikaler Scrollbalken wird immer angezeigt, auch 
        // wenn sich wenig Meldungen in der JTextArea befinden.
        sp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);        

        // Erzeugt ein GridBagLayout
        myGBL_10_1 = new GridBagLayout();        
        //myGL21 = new GridLayout(3, 1);
        addiereKopmonente(myGBL_10_1, myRenameButton, 0, 0, 1, 1, 1, 1);
        // weightx = 3 bedeutet, dass Buttom myb1 dreimal so breit ist
        // wie myb1
        addiereKopmonente(myGBL_10_1, myMeldungenLabel, 0, 1, 1, 1, 1, 1);        
        
        addiereKopmonente(myGBL_10_1, sp, 0, 2, 1, 8, 1, 20);        
        
        myPan.setLayout(myGBL_10_1);

        //myWanze = new MyWanze();        
        myWanze = new MyWanze(myMeldung);
        // Montiert die Wanze an den Button
        myRenameButton.addActionListener(myWanze);
        // Montiert die Buttons an die Zeichenfläche
        myPan.add(myRenameButton);
        myPan.add(myMeldungenLabel);
        myPan.add(sp);                

        // Montiert die Zeichenfläche in das Fenster MyFenster
        myCont.add(myPan);
        // Fensterüberschrift festlegen
        setTitle("Ein Umbenennungsprogramm");
        // Koordinaten des linken, oberen Ecks des Fensters festlegen
        // Koordinate x = 100, Koordinate y = 200.
        setLocation(10, 200);
        // Die Breite des Fensters in x-Richtung 
        // Die Breite des Fensters in y-Richtung 
        setSize(800, 400);
        // Macht das Fenster sichtbar
        setVisible(true);
    }
    
    
    public void addiereKopmonente(GridBagLayout gbl, Component c, int x, int y, int width, int height, double weightx, double weighty){
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.BOTH;
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.gridwidth = width;
        gbc.gridheight = height;
        gbc.weightx = weightx;
        gbc.weighty = weighty;
        // Beschränkung für Komponente c (z.B. Button)am Layout-Manager anmelden.
        gbl.setConstraints(c, gbc);
        add(c);
    }
    
}

class MyWanze implements ActionListener{
    public JTextArea myMeldung;
    
    //public MyWanze() {
    public MyWanze(JTextArea myMeldung) {        
        this.myMeldung=myMeldung;        
    }

    public void actionPerformed(ActionEvent ae) {
        FileOderDirectoryRename myF = new FileOderDirectoryRename();
            myF.renameMenue(ae,myMeldung);
    }
}

class FileOderDirectoryRename {
    public JTextArea myMeldung;
    public int zaehler = 0;
    public int merke=0;
    public Component comp[];
    
    public void renameMenue(ActionEvent ae, JTextArea myMeldung){
        int j = 0;
        int option = 0;
        this.myMeldung=myMeldung;         
        
       

        
        /* Sonderbar:
        Wenn folgendes gemacht wird, reagiert das Programm anders:
        Container con;        
        con = ((JButton) (ae.getSource())).getParent();        
        */

        // Ein Dialogfenster (eine Art Explorer) erzeugen. 
        // In diesem können Dateien und Verzeichnisse ausgewählt werden.
        // Ohne solch einen Dialog kommt fast kaum eine Anwendung aus. 
        // Für diesen Zweck gibt es in Java die Klasse:
        // javax.swing.JFileChooser 
        JFileChooser chooser = new JFileChooser();
        // Es werden Directorys und Files angezeigt
        chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
        // Es können mehrere Directorys/Files markiert werden
        chooser.setMultiSelectionEnabled(true);
        // Button auf dem JFileChooser mit Aufschrift "Umbenennung starten" 
        // erzeugen
        chooser.setApproveButtonText("Umbenennung starten");
        // Dialogmenü anzeigen
        option = chooser.showDialog(null, null);

        if (option == JFileChooser.APPROVE_OPTION) {
            // markierte Directorys bzw. Files in dirFiles abspeichern
            File[] dirFiles = chooser.getSelectedFiles();

            myMeldung.append("\nBitte warten ...");             

            
            // Alle markierten Directorys bzw. Files umbenennen
            for (int i = 0; i < dirFiles.length; i++) {
                try{
                    renameTree(dirFiles[i]);
                }
                catch(Throwable t){
                    if(t instanceof MyException){
                        myMeldung.append("\n"+((MyException) t).throwMeldung); 
                        System.out.println("\n"+((MyException) t).throwMeldung);
                    }
                    else{
                        System.out.println("Meldung in renameMenue(): "+t.getMessage()+"\n");  
                        myMeldung.append("\n"+t.getMessage());    
                        t.printStackTrace();       

                    }
                }
            }
            myMeldung.append("\nEnde des Umbenennungsvorgangs");     
            System.out.println("\nEnde des Umbenennungsvorgangs"); 
        } else {
            myMeldung.append("\nAbbruch");            
        }
    }

    /*    
    public void deleteFileOderDirectory(File dir){
        File[] files=dir.listFiles();
        if(files !=null){
            for(int i=0; i < files.length; i++){
                if(files[i].isDirectory()){
                    //System.out.println("files["+i+"]"+files[i].getName());
                    deleteFileOderDirectory(files[i]);
                }
                else{
                    //System.out.println("files["+i+"]"+files[i].getName());
                    files[i].delete();
                }
            }
        }
        // System.out.println("dir"+dir.getName());
        dir.delete();
     }
*/


/*    
    public void fehlermeldung(String s){
       myMeldung.append(s);            
    }    
*/    
    

    // Prüft, ob ein Knoten eines Verzeichnisbaums ein Blatt ist
    public boolean isLeaf(File node) throws Throwable{
        boolean blatt=false;
        File[] files;
        String throwString;
        // Throwable myt;
        MyException myEx;
     
        try{
            if(node.isFile()){
                blatt=true;
            }
        }
        catch(Throwable t){
            throwString = "\nF E H L E R - M E L D U N G :  Lesebzugriff zur Datei nicht erlaubt:\n"+node;
            System.out.println(throwString); 
            myEx = new MyException(throwString, true);
           throw myEx;            
        }    

        try{
            if(node.isDirectory()){
                files = node.listFiles();
                if(files.length==0){
                    blatt=true;
                }
                else{
                blatt=false;
                }
            }
        }
        catch(Throwable t){
            throwString = "\nF E H L E R - M E L D U N G :  Lesebzugriff zum Verzeichniss nicht erlaubt:\n"+node;
            System.out.println(throwString); 
            myEx = new MyException(throwString, true);
            throw myEx;            
        }    
        return blatt;
    }
    

    
    // Umbenennen eines Knotens eines Verzeichnisbaums 
    public boolean renameNode(File dir) throws Throwable{
        boolean merke=false;
        boolean namensVergleich;
        boolean erg=true;        
        int i;

        String umbenennungString;
        String temp;        
        String[] strings=null;
        File parent;
        ArrayList checkliste;        
        MyException myEx=new MyException("\n", true);
        File f=null;
        File parentFile;
        String throwString="";
       
        // bei getParentFile() gibt es keine Exception                
        parent = dir.getParentFile();
        if (parent == null) {
            throwString = "\nF E H L E R - M E L D U N G :  Es gibt kein Parent-Verzeichnis von:\n"+dir;
            System.out.println(throwString); 
            myEx = new MyException(throwString, true);
            throw myEx;            
        }

        try{
          // Liste des Oberverzeichnisses
            strings = parent.list();
        }
        catch (Throwable t){
            throwString = "\nF E H L E R - M E L D U N G :  Lesebzugriff zum nicht erlaubt von Verzeichnis:\n"+parent;
            System.out.println(throwString); 
            myEx = new MyException(throwString, true);
            throw myEx;            
        }

        checkliste = new ArrayList();

        for (i = 0; i < strings.length; i++) {
             // bei add gibt es keine Exception                            
             checkliste.add(strings[i]);
        }

        // bei getName gibt es keine Exception                
        temp = dir.getName();

        // bei remove gibt es keine Exception        
        checkliste.remove(temp);

        Liste mylist = new Liste();

        // bei ersetzenVorschlag gibt es keine Exception
        umbenennungString = mylist.ersetzenVorschlag(checkliste);

        // bei dir.getParentFile() gibt es keine Exception            
        parentFile=dir.getParentFile();

        try{        
            f = new File(parentFile, umbenennungString);
        }
        catch (Throwable t){
            throwString="\nF E H L E R - M E L D U N G umbenennungString ist null von:\n";
            System.out.println(throwString); 
            myEx = new MyException(throwString, true);
            throw myEx;            
        }
        
        
        // bei getName() und  equals() gibt es keine Exception        
        namensVergleich=f.getName().equals(dir.getName());
        try{
            // Wenn neuer Pfadname == altem Pfadname, dann gibt es beim 
            // Umbennenen einen Fehler --> siehe Java-API
            // 
            if(namensVergleich==false){
                erg=dir.setWritable(true, false);
                if(erg==false){
                    throwString = "\nF E H L E R - M E L D U N G beim Vergeben von Schreibrechten bei\n"+f;
                    System.out.println(throwString);
                    // merke=true;
                    myEx = new MyException(throwString, true);
                    throw myEx;            
                }
            }
        }
        catch (Throwable t){
            // Bei praktischen Tests klappt die Vergabe von Schreibrechten nicht.
            // Deswegen soll das Programm weitermachen, aber den Fehler ausgeben. 
            throwString += "\nF E H L E R - M E L D U N G beim Vergeben von Schreibrechten bei\n"+f;
            System.out.println(throwString);
            //merke = true;
            myEx = new MyException(throwString, false);
            
        }

        try{
            if(namensVergleich==false){ 
                erg=dir.renameTo(f);            
                if(erg==false){
                    throwString += "\nF E H L E R - M E L D U N G beim Umbenennen von\n" +dir+ "\n nach \n"+f;
                    System.out.println(throwString);
                    myEx = new MyException(throwString, false);
                }
            }
        }
        catch (Throwable t){
            throwString +="\nF E H L E R - M E L D U N G Schreibzugriff beim Umbenennen (auf alten oder neuen Pfadnamen) von:\n"+dir+"\n nach \n"+f;
            throwString=throwString+"\n oder Parameter " + "ist null";                 
            System.out.println(throwString);
            myEx = new MyException(throwString, false);
        }

        if(myEx.sofortAbbruch==false){
            throw myEx;
        }
        return erg;
    }
      

    // Jeder Knoten (eauch Files) Verzeichnisbaums wird umbenannt.
    public void renameTree(File node) throws Throwable{
        int i;
        boolean erg;
        String umbenennungString;
        File[] files=null;
        String throwString;
        MyException myEx; 
     
        try{
            // Achtung: wenn node kein Directory dann null als Ergebnis
            files = node.listFiles();
            if(files==null){
                System.out.println("Hallo");
            }
        }
        catch (Throwable t){
            //melde ="\nF E H L E R - M E L D U N G :  Lesebzugriff nicht erlaubt von:\n"+node;
            throwString="\nF E H L E R - M E L D U N G :  Lesebzugriff nicht erlaubt von:\n"+node;            
            System.out.println("\n"+throwString);                        
            throw t;
        }

        try{
            if (isLeaf(node)) {
                //System.out.println("rename "+node.getName());
                renameNode(node);
                return;
            }
            else{
                for (i = 0; i < files.length; i++) {
                    //System.out.println("rename "+files[i].getName());                    
                    renameTree(files[i]);
                }
                //System.out.println("rename "+node.getName());                                    
                renameNode(node);            
            }
        } 
        catch (Throwable t){
            if(t instanceof MyException){
                if ( ((MyException) t).sofortAbbruch == false){
                    myMeldung.append(((MyException) t).throwMeldung);
                }
            }
            else{
                System.out.println("Meldung in renameMenue(): "+t.getMessage()+"\n");  
                myMeldung.append("\n"+t.getMessage());    
                t.printStackTrace();       
                throw t;                
            }
        }
    }
}


class MyException extends Throwable{
    public boolean sofortAbbruch;
    public  String throwMeldung;
    
    public MyException(String throwMeldung, boolean sofortAbbruch) {
        this.throwMeldung = throwMeldung;
        this.sofortAbbruch = sofortAbbruch;
    }

    public boolean getSofortAbbruch() {
        return sofortAbbruch;
    }

    public void setSofortAbbruch(boolean sofortAbbruch) {
        this.sofortAbbruch = sofortAbbruch;
    }
}


                
class Liste {

    private ArrayList moeglicheNamen;

    public Liste() {
        moeglicheNamen = erzeugenamensliste();
    }

/*    
    public ArrayList entferne(ArrayList pl, int i) {
        ArrayList temp;
        temp = new ArrayList(pl);
        temp.remove(i);
        return temp;
    }
*/
    public ArrayList erzeugeArrayList(File[] files) {
        int i;
        ArrayList temp;
        temp = new ArrayList();
        for (i = 0; i < files.length; i++) {
            temp.add(files[i]);
        }
        return temp;
    }

    public String ersetzenVorschlag(ArrayList checkliste) {
        ArrayList temp;
        String vorschlagStr;
        String ergStr = null;
        Boolean b;
        int i;
        i = 0;
        while (i < moeglicheNamen.size()) {
            vorschlagStr = (String) moeglicheNamen.get(i);
            // bei contains gibt es keine Exception
            b = checkliste.contains(vorschlagStr);
            if (b == false) {
                ergStr = vorschlagStr;
                return ergStr;
            }
            i++;
        }
        return ergStr;
    }

    /*
    Die Liste der möglichen Namen aller Knoten des Verzeichnisbaums:
    a,b,...,z,0,...,9,
    aa ... a9, ba .... b9, ... 9a, ..., 99
    aaa, ..., 999
    
    Mit duesen Namen werden alle Knoten des Verzeichnisbaums ersetzt,
    wobei möglichst einstellige Namen (also, a,b, ... 9) bevorzugt werden.
    */
    ArrayList erzeugenamensliste() {
        int i, j, k;
        ArrayList basisliste;
        ArrayList namensliste;
        ArrayList ziffernliste;
        ArrayList buchstabenliste;

        basisliste = new ArrayList<String>();
        ziffernliste = new ArrayList<String>();
        buchstabenliste = new ArrayList<String>();
        namensliste = new ArrayList<String>();

        // Ascii-Wert von a = 97
        // Ascii-Wert von z = 122
        // Ascii-Wert von 0 = 48
        // Ascii-Wert von 9 = 57
        for (i = 97; i <= 122; i++) {
            buchstabenliste.add(String.valueOf((char) i));
        }

        for (i = 48; i <= 57; i++) {
            ziffernliste.add(String.valueOf((char) i));
        }

        basisliste.addAll(buchstabenliste);
        basisliste.addAll(ziffernliste);

        namensliste.addAll(basisliste);

        for (i = 0; i < basisliste.size(); i++) {
            for (j = 0; j < basisliste.size(); j++) {
                String str1;
                String str2;
                str1 = (String) basisliste.get(i);
                str2 = (String) basisliste.get(j);
                String str = str1 + str2;
                namensliste.add(str);
            }
        }

        for (i = 0; i < basisliste.size(); i++) {
            for (j = 0; j < basisliste.size(); j++) {
                for (k = 0; k < basisliste.size(); k++) {
                    String str1;
                    String str2;
                    String str3;
                    str1 = (String) basisliste.get(i);
                    str2 = (String) basisliste.get(j);
                    str3 = (String) basisliste.get(k);
                    String str = str1 + str2 + str3;
                    namensliste.add(str);
                }
            }
        }
        return namensliste;
    }
}
 
In der folgenden Methode unten wird nach return _nicht_ die Methlode verlassen, sondern an der Stelle (XXX)
weitergemacht. Kann das sein ??
Ja, das kann sein oder besser: es kann so aussehen als ob. Grund ist die Rekursion im else-Zweig.

Wenn in renameTree das erste mal isLeaf(node) false liefert und somit der else-Zweig betreten wird, wird in einer Schleife die Methode erneut (ggf. mehrfach) aufgerufen. Wenn dieser verschachtelte Aufruf mit einem return zurückkehrt, wird der Code nach dem Methodenaufruf - also in der Schleife - fortgesetzt.

Für Dich siehst es dann so aus, als würdest Du nicht aus der Methode kommen, tatsächlich musst Du jeden Methodenaufruf aber separat betrachten.
 

Neue Themen


Zurück
Oben