Java read java file and extract classes and methods

If you want to read java file and print only the class and method names than you can use regular expression to extract this information:

Note: This post is based on request of a blog user. So I decided answer each week one question from blog or youtube users. Feel free to ask in the comments below or on the youtube channel:

Softhints on Youtube

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ReadJavaFile {

    public static void main(String[] args) {
        readJavaFile();
        extractJavaFile();
    }

    //method for openning text file
    static void readJavaFile() {
        try {
            BufferedReader input = new BufferedReader(
                    new FileReader("/home/user/java/src/main/java/Fibber.java"));
            String line;
            while ((line = input.readLine()) != null)
                System.out.println(line);
            input.close();
        } catch (IOException ex) {
            System.err.println("Error occured");
        }
    }

    //method for openning text file
    static void extractJavaFile() {
        try {
            BufferedReader input = new BufferedReader(
                    new FileReader("/home/user/java/src/main/java/Randoma.java"));
            String line;
            while ((line = input.readLine()) != null)
                if(filterLines(line) != "") {
                    System.out.println(filterLines(line).trim());
                }
            input.close();
        } catch (IOException ex) {
            System.err.println("Error occured");
        }
    }

    static String filterLines(String line) {
        String out, flag = "";
        List<String> method = new ArrayList<>();

        Pattern reMethod= Pattern.compile("(public|private|protected)(.*\\)).*\\{");        //match method by public, private or protectec, followed by anything with border ) {
        Matcher matchMethod = reMethod.matcher(line);

        while (matchMethod.find()) {
            method.add(matchMethod.group());
        }

        if(line.contains("class")){
            flag = "class";
        };
        if(method.size() > 0){
            flag = "method";
        };
        switch (flag) {
            case "class": out = line.replaceAll("(?:public|private|protected)\\s?(class) (\\w+) \\{", "$1 name: $2");break; // for a class line output: class name: class name: Class
            
            //for method output:
            //--- method name: main, 
            //------ parameters: String... aArgs {
            case "method": out = line.replaceAll(" (?:public|private|protected)? (?:static)? (?:final)?\\s?(?:void|int)? (\\w+)\\((.*)\\)", "--- method name: $1, \n------ parameters: $2");break;
            default: out = "";break;
        }

        return out;
    }
}

result:

class name: Randoma
--- method name: main,
------ parameters: String... aArgs {
--- method name: count,
------ parameters: List items {
--- method name: randomRange,
------ parameters: int min, int max {

If you like to get whole content of the file you can use method:extractJavaFile().

Explanation of the regex:

  • search for class line - if the line contains class - here you can addopt it to your needs to skip comments
if(line.contains("class")){
  • search method line - if the code line start by any of these: public, private, protected and ends in ) { - is treated as a method
Pattern reMethod= Pattern.compile("(public|private|protected)(.*\\)).*\\{"); 
  • extract method information:
  • (?:public|private|protected)?
  • ?: - a non capture group - it is not included in the final result.
  • ? - find 0 or 1
  • (\w+) - extract any word
  • \((.*)\) - extract anything enclosed by ( and )

You can have very good visual explanation here:
regexper by putting:

(?:public|private|protected)? (?:static)? (?:final)?\s?(?:void|int)? (\w+)\((.*)\)

case "method": out = line.replaceAll(" (?:public|private|protected)? (?:static)? (?:final)?\\s?(?:void|int)? (\\w+)\\((.*)\\)", "--- method name: $1, \n------ parameters: $2");break;
            default: out = "";break;

Here you can find the class Fibber and Randoma:

  • Fibber
class Fibber {

    public static void main(String[] args) {
        Fibber fibber = new Fibber();
        while(fibber.current < 100) fibber.next();
        System.out.println(fibber.fib);
    }

    int old=1,fib=1,current=1;

    int next() {
        int newFib=fib+old;
        old=fib;
        fib=newFib;
        current++;
        return  fib;
    }
}
  • Randoma
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Randoma {

    public static final void main(String... aArgs) {

        Random randomGenerator = new Random();

        ArrayList<Integer> items = new ArrayList<Integer>(1000);


        for (int idx = 1; idx <= 1000; ++idx) {
            int randomInt = randomGenerator.nextInt(100);
            System.out.println(randomInt);
            items.add(randomInt);
        }
        count(items);

        ArrayList<Integer> itemsR = new ArrayList<Integer>(1000);

        for (int idx = 1; idx <= 1000; ++idx) {
            int randomInt = randomRange(20, 100);
            System.out.println(randomInt);
            itemsR.add(randomInt);
        }
        count(itemsR);
    }
    
    private static void count(List<Integer> items) {
        Map<Integer, Long> result =
                items.stream().collect(
                        Collectors.groupingBy(
                                Function.identity(), Collectors.counting()
                        )
                );
        result.forEach((item, value) -> System.out.println(item + " - " + value));
    }

    private static int randomRange(int min, int max) {
        if (min >= max) {
            throw new IllegalArgumentException("error");
        }
        Random r = new Random();
        return r.nextInt((max - min) + 1) + min;
    }
}

Related Article