2016-11-28 22 views
7

C# 6.0 giới thiệu toán tử nameof(), trả về một chuỗi biểu thị tên của bất kỳ lớp/hàm/phương thức/biến địa phương/thuộc tính nào được đặt bên trong nó.nameof tương đương trong Java

Nếu tôi có một lớp học như thế này:

class MyClass 
{ 
    public SomeOtherClass MyProperty { get; set; } 

    public void MyMethod() 
    { 
     var aLocalVariable = 12; 
    } 
} 

tôi có thể sử dụng toán tử như thế này:

//with class name: 
var s = nameof(MyClass); // s == "MyClass" 

//with properties: 
var s = nameof(MyClass.OneProperty); // s == "OneProperty" 

//with methods: 
var s = nameof(MyClass.MyMethod); // s == "MyMethod" 

//with local variables: 
var s = nameof(aLocalVariable); // s == "aLocalVariable". 

này rất hữu ích từ chuỗi chính xác được kiểm tra tại thời gian biên dịch. Nếu tôi sai chính tả tên của một số thuộc tính/phương thức/biến thì trình biên dịch trả về lỗi. Ngoài ra, nếu tôi refactor, tất cả các chuỗi được tự động cập nhật. Xem ví dụ this documentation cho các trường hợp sử dụng thực tế.

Có tương đương với toán tử đó trong Java không? Nếu không, làm thế nào tôi có thể đạt được kết quả tương tự (hoặc tương tự)?

+2

Đẹp, chắc chắn Java không có bất cứ điều gì chính xác tương đương. Vì vậy, như trước C# 6 bạn có thể sẽ chỉ phải sử dụng chuỗi ký tự thay thế. – juharr

+0

'nameof' là cú pháp được thêm vào trong phiên bản mới nhất của C# (6).Tôi khá chắc chắn rằng Java (hoặc các ngôn ngữ phổ biến nhất nói chung) sẽ không có một tương đương. – Abion47

+5

Bạn đang cố gắng giải quyết vấn đề gì với khả năng này? – OldProgrammer

Trả lời

9

Đáng buồn thay, không có gì giống như thế này. Tôi đã được tìm kiếm chức năng này một khi trở lại và câu trả lời có vẻ là nói chung, công cụ này không tồn tại.

Xem Get name of a field

Bạn có thể, tất nhiên, chú thích lĩnh vực của bạn với một chú thích "tên" để cơ bản hoàn thành mục tiêu này cho các lớp học của riêng bạn. Có rất nhiều khung công tác phụ thuộc vào các khái niệm tương tự. Mặc dù vậy, đây không phải là tự động.

6

Bạn không thể.

Bạn có thể lấy Phương thức hoặc Trường bằng phản chiếu, nhưng bạn phải mã hóa tên phương thức dưới dạng Chuỗi, giúp loại bỏ toàn bộ mục đích.

Khái niệm về các thuộc tính không được tích hợp vào java như trong C#. Getters và setters chỉ là phương pháp thông thường. Bạn thậm chí không thể tham chiếu một phương thức dễ dàng như bạn làm trong câu hỏi của mình. Bạn có thể thử xung quanh với sự phản chiếu để có được một xử lý cho một phương thức getter và sau đó cắt bỏ các get để có được tên của "tài sản" nó tương tự, nhưng đó là xấu xí và không giống nhau.

Đối với các biến cục bộ, hoàn toàn không thể.

+1

Câu hỏi này không liên quan gì tới các thuộc tính của C#. Câu hỏi đặt ra là hỏi xem bạn có thể lấy tên của một phương thức hoặc trường mà không sử dụng tên của chính nó hay không. Điểm của bạn về sự phản chiếu đòi hỏi tên để có được Phương thức hoặc Trường là mầm. –

+0

Câu hỏi đề cập đến đặc tính C# rất cụ thể. Và tôi trả lời câu hỏi bằng "không". Vì vậy, tại sao downvote? Ngoài ra, "germane" có nghĩa là gì? – f1sh

+1

Ok, tôi đã đề cập đến các thuộc tính C#, nhưng rõ ràng chúng không tồn tại trong Java. Đó chỉ là một ví dụ. Điểm của câu hỏi của tôi là để có được các thành viên lớp/biến/trường/mã định danh biểu diễn chuỗi và bạn đã trả lời bằng một số điều hữu ích. –

3

Bạn không thể.

Nếu bạn biên dịch với các biểu tượng gỡ lỗi thì tệp .class sẽ chứa một bảng tên biến (đó là cách trình gỡ lỗi ánh xạ các biến trở lại mã nguồn của bạn), nhưng không đảm bảo điều này sẽ có và nó không được hiển thị trong thời gian chạy.

+0

Câu hỏi đặt ra trước tiên về tên của các lớp, các phương thức và các trường, được bao gồm trong mã được biên dịch và được hiển thị thông qua sự phản chiếu. –

+1

@AndyThomas không, nó không. Dừng downvoting câu trả lời đúng. – f1sh

+0

tốt sẽ @ f1sh –

3

Có thể thực hiện bằng cách sử dụng thiết bị mã byte thời gian chạy, ví dụ sử dụng thư viện Byte Buddy.

Xem thư viện này: https://github.com/strangeway-org/nameof

Phương pháp này được mô tả ở đây: http://in.relation.to/2016/04/14/emulating-property-literals-with-java-8-method-references/

Cách sử dụng Ví dụ:

public class NameOfTest { 
    @Test 
    public void direct() { 
     assertEquals("name", $$(Person.class, Person::getName)); 
    } 

    @Test 
    public void properties() { 
     assertEquals("summary", Person.$(Person::getSummary)); 
    } 
}