cuốn sách gpt4 ai đã làm

Javassist: Sao chép phương thức với thông tin gỡ lỗi?

In lại Tác giả: Vũ trụ không gian Thời gian cập nhật: 2023-11-04 12:32:53 26 4
mua khóa gpt4 Nike

Trong một số lượng lớn các lớp bắt nguồn từ lớp tổ tiên công khai, tôi có các phương thức thứ gì đó() , Tôi muốn sửa đổi hành vi của nó để đo thời gian thực hiện. Tôi có hai phương thức bổ sung được định nghĩa trong lớp tổ tiên công khai

// trong lớp tổ tiên chung:
// phương thức này được định nghĩa trong tất cả các lớp dẫn xuất
công khai làm mất đi thứ gì đó() {
System.out.println("cái gì đó{");
System.out.println("cái gì đó}");
}
// phần thân của phương thức này sẽ thay thế phần thân của something()
khoảng trống công khai được đoS Something() {
System.out.println("measuredSomething{");
roomForS Something();
System.out.println("measuredSomething}");

}
// phần thân của phương thức này sẽ được thay thế bằng phần thân của something()
phòng trống công khaiForSomething() {
// mã này sẽ được thay thế bằng mã khác
System.out.println("roomForSomething{");
System.out.println("roomForSomething}");
}

Tôi sử dụng Javassist để thay thế:

// someClass đã được biết
Chuỗi superClassName = someClass.getName();
Chuỗi className = superClassName + "__proxy";
CtClass ctSuperClass = ClassPool.getDefault().get(superClassName);
CtClass ctClass = ClassPool.getDefault().makeClass(className);
ctClass.setSuperclass(ctSuperClass);

// roomForS Something := thứ gì đó
Phương thức CtMethodSomething = ctSuperClass.getMethod("something", "()V");
Phương thức CtMethodSomething2 = CtNewMethod.copy(methodSomething, "roomForSomething", ctClass, null);

ctClass.addMethod(methodSomething2);

// cái gì đó := đo được cái gì đó
// (và đoS Something() sẽ gọi roomForSomething())
Phương thức CtMethodMeasuredSomething = ctSuperClass.getMethod("measuredSomething", "()V");
Phương thức CtMethodMeasuredSomething2 = CtNewMethod.copy(methodMeasuredSomething, "something", ctClass, null);

ctClass.addMethod(methodMeasuredSomething2);

someClass = ctClass.toClass();
result = someClass.newInstance();

Và nó hoạt động. Nhưng trình gỡ lỗi không thể hiển thị mã được thực thi.

Làm cách nào tôi có thể sao chép thông tin gỡ lỗi cùng với mã byte để trình gỡ lỗi hiển thị mã nguồn đang được thực thi?

(Không thể thực hiện được khi sửa đổi mã phương thức, nhưng có thể thực hiện được trong trường hợp cụ thể này.)

((Tôi khuyên bạn nên thay đổi phương pháp thứ gì đó() chia thành hai phương thức, như thể để ghi đè Thread.run() và gọi Chủ đề.start() Như nhau. Tôi được yêu cầu tránh những thay đổi như vậy. ))

gia hạn

Cách tiếp cận sau đây cho kết quả tốt hơn: trình gỡ lỗi chỉ dừng ở hàm được tạo bởi CtMethod.make() khi quay về từ hàm được gọi; hàm được tạo sẽ hiển thị trong dấu vết ngăn xếp;

// cái gì đó := đo được cái gì đó
CtMethod MethodSomething = CtMethod.make("public void something() {super.measuredSomething();}", ctClass);
ctClass.addMethod(methodSomething);

// roomForS Something := thứ gì đó
Phương thức CtMethodRoomForSomething = CtMethod.make("public void roomForSomething() {super.something();}", ctClass);
ctClass.addMethod(methodRoomForSomething);

Sẽ thật tuyệt nếu mã nguồn của hàm được tạo có thể được hiển thị.

câu trả lời hay nhất

Tôi không nghĩ bạn có thể gỡ lỗi trực tiếp mã được chèn bằng Javassist, vì thư viện này chỉ có thể sửa đổi mã byte (vì vậy mã nguồn thực tế không bị thay đổi). Điều này có nghĩa là trình gỡ lỗi của bạn không thể truy cập mã bạn đưa vào vì về cơ bản nó không tồn tại (chỉ là một cách đồ họa để thể hiện các hoạt động mã byte của bạn).

BTW, tôi gặp vấn đề tương tự và mục tiêu của tôi là gỡ lỗi phương thức roomForS Something. Giải pháp của tôi là thế này: trước tiên hãy khai báo phương thức bạn muốn gỡ lỗi (roomForSomething() trong trường hợp của bạn) trong lớp và đặt nó ở dạng tĩnh.

gói trọn gói;
lớp công khai ClassName{
public static void roomForSomething(){
// ở đây bạn có thể gỡ lỗi
}
}

Sau đó, bạn có thể sử dụng Javassist để đưa lệnh gọi phương thức tĩnh này vào phương thức đã sửa đổi. Ngay cả khi lớp mà bạn định nghĩa "roomForSomething" không được nhập, bạn vẫn có thể chỉ định tên đủ điều kiện của lớp như tôi đã làm trong ví dụ.

// roomForS Something := thứ gì đó
Phương thức CtMethodRoomForSomething = CtMethod.make("public void RandomName() {packageClassName.roomForSomething()}", ctClass);
ctClass.addMethod(methodRoomForSomething);

Bằng cách sử dụng giải pháp này, bạn có thể đặt điểm ngắt trong mã "roomForS Something".

Giới thiệu về Javassist: Sao chép các phương thức có thông tin gỡ lỗi? , chúng tôi đã tìm thấy một câu hỏi tương tự trên Stack Overflow: https://stackoverflow.com/questions/37658582/

26 4 0
không gian vũ trụ
Hồ sơ

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá taxi Didi miễn phí
Phiếu giảm giá taxi Didi
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress