Lấy tất cả phương thức static trong 1 tệp Java

E có tìm được bài viết này 2 năm trước, tuy nhiên e vẫn chưa giải quyết được bài này ạ

Với hệ thống web chấm thì k thể dùng javac được ạ( giá sử có trường hợp file .java gồm package nơi khác thì biên dịch sẽ bị lỗi) . Mọi người cho e xin hướng đi,cách giải chi tiết hơn với ạ.

Link bài viết ạ: Lấy tất cả phương thức static trong 1 tệp - Java

Đề bài: cài đặt phương thức List<String> getAllFunctions(String fileContent) để lấy toàn bộ chữ ký các phương thức static (method signature) trong một tệp cho trước qua các phép xử lý xâu, trong đó fileContent là nội dung tệp bạn cần xử lý. Mỗi một phần tử String trong đối tượng trả về lưu mã nguồn phương thức static tìm được.

Định dạng chữ ký phương thức được quy định theo định dạng:

methodName(parameter1_type,parameter2_type,...)

Chú ý là parameter1_type, parameter2_type,… phải là Fully Qualified Type Name

Dưới đây là một số ví dụ:

public static void sayHello() {}
=> sayHello()
---------------------------------------------
public static int add(int a, int b) {}
=> add(int,int)
---------------------------------------------
public static void printMessage(String message) {}
=> printMessage(java.lang.String)
---------------------------------------------
public static void printMessages(String[] messages) {}
=> printMessages(java.lang.String[])
---------------------------------------------
import java.io.File;
public static String readFile(File file) {}
=> readFile(java.io.File)
---------------------------------------------
// tệp này có 2 lớp
package net.bqc.utils;
class Message {}
public static void printMessage(Message message) {}
=> printMessage(net.bqc.utils.Message)
---------------------------------------------
// tệp này có 2 lớp
package net.bqc.utils;
import java.util.List;
class Message {}
public static void printMessages(List<Message> messages) {}
=> printMessages(java.util.List<net.bqc.utils.Message>)

Chà! Có khi bạn làm xong bài này thì bạn có thể tự viết một trình biên dịch được luôn.
Bài này không đơn giản là xử lý chuỗi nữa, bạn phải xử lý, lưu trữ và liên kết chúng với nhau.

Trước hết là làm từ đơn giản như thứ tự các ví dụ mẫu thôi. Xử lý và nhận dạng sao cho ra được kết quả được như 4 ví dụ đầu.
Phần packageimport là đến lúc bạn phải lưu trữ và liên kết với các tham số.

1 Like

vâng anh, anh nghĩ sao về hướng reflection cũ, nếu reflect thì việc lấy ra mẫu khá đơn giản nhưng vấn đề là nó phải là file .java ạ, để làm được điều này theo anh nói (viết 1 trình biên dịch ngay trong chương trình) thì e có tìm thấy nạp động (dynamic class loading) nhưng 1 file có package thì k thể biên dịch được ạ :>, còn nếu xử lý xâu đơn thuần thì việc lấy ra các yêu cầu như “java.lang.String” thì e chưa biết làm thế nào ạ :v
em chưa hiểu việc lưu trữ và liên kết là như thế nào luôn ạ :((

Cậu có thể nói rõ hơn về vấn đề của cậu được không? Cụ thể cậu muốn làm sản phẩm, hay chỉ giải quyết 1 bài tập về nhà đơn giản?

Hướng mà @SITUVN.gcd đề cập đúng đó, cơ mà cậu không cần tới cả compiler. Cậu chỉ cần Java parser thôi (một bộ phận của compiler dùng để chuyển source code thành cây cú pháp Abstract syntax tree, mà không quan tâm tới ngữ nghĩa source code đó có đúng không). Sau khi có ABT, cậu chỉ cần duyệt và lấy node method nếu có sự xuất hiện của static keyword.
Thử tham khảo link ở trên (dù tớ chưa làm việc với Java Parser bao giờ, cơ mà khả năng là nó hoạt động như tớ giải thích ở trên), trong đó có dẫn tới homepage chứa ebook của Java Parser đó.

Reflection cậu thấy vấn đề rồi, cậu phải có source biên dịch được (phải có cả các dependency của source). Cách đó sẽ không giải quyết vấn đề của cậu đâu trọn vẹn đâu.

Hope it helps!

2 Likes

vậy, Java parser tức là mình phải cài đặt với project đúng không ạ, vấn đề của em chỉ là bài tập ạ, và yêu cầu là e phải submit 1 hay nhiều file .java của mình nên e chưa biết áp dụng cách này như thế nào ạ

Oh, vậy là cậu chỉ làm bài tập nho nhỏ thôi phải ko? :smile:
Nếu thế thì regex là lựa chọn tốt hơn cho cậu đó. Cậu chỉ cần cài đặt 1 giải thuật như này:

  • Đọc từng dòng một.
    • Nếu dòng đó có từ khóa static:
      • Kiểm tra từ khóa đó có nằm trong 1 xâu nào không.
      • Loại bỏ các comment, dấu cách thừa…, và kiểm tra dòng đó có match regex cho 1 method hay không.

Vậy thôi :smile:

2 Likes

vâng, vậy ví dụ method có tham số kiểu String, yêu cầu khi trả về sẽ phải là đầu dẫn: (“java.lang.String”) hoặc các đường dẫn package ạ, và cái này mình sẽ regex như thế nào ạ :((

Cái này chắc không phải là RegEx nữa, bạn lưu và nối vào thôi.
Mặc định trong Java, gói java.lang.* sẽ được import sẵn cho dù không khai báo nó, nên các lớp cơ bản sẽ có sẵn.

3 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?