web-development-kb-asia.site

(không) Thuộc tính trong Java?

Vì vậy, tôi đã cố tình giữ cho mình một Java n00b cho đến gần đây và lần tiếp xúc thực tế đầu tiên của tôi đã gây ra một cú sốc nhỏ: Java không có các thuộc tính kiểu C #!

Ok, tôi có thể sống với điều đó. Tuy nhiên, tôi cũng có thể thề rằng tôi đã thấy mã getter/setter thuộc tính trong Java trong một cơ sở mã, nhưng tôi không thể nhớ nơi nào. Làm thế nào mà đạt được? Có một phần mở rộng ngôn ngữ cho điều đó? Nó có liên quan đến NetBeans hay cái gì không?

53
Ishmaeel

Có một mẫu "tiêu chuẩn" cho getters và setters trong Java, được gọi là Thuộc tính Bean . Về cơ bản, bất kỳ phương thức nào bắt đầu bằng get, không có đối số và trả về giá trị, là một công cụ nhận thuộc tính cho một thuộc tính có tên là phần còn lại của tên phương thức (với một chữ cái bắt đầu thấp hơn). Tương tự như vậy set tạo một setter của một phương thức void với một đối số duy nhất.

Ví dụ:

// Getter for "awesomeString"
public String getAwesomeString() {
  return awesomeString;
}

// Setter for "awesomeString"
public void setAwesomeString( String awesomeString ) {
  this.awesomeString = awesomeString;
}

Hầu hết các IDE Java sẽ tạo ra các phương thức này cho bạn nếu bạn hỏi chúng (trong Eclipse đơn giản như việc di chuyển con trỏ đến một trường và nhấn ctrl-1, sau đó chọn tùy chọn từ danh sách).

Để biết giá trị của nó, để dễ đọc, bạn thực sự có thể sử dụng ishas thay cho get cho các thuộc tính kiểu boolean, như trong:

public boolean isAwesome();

public boolean hasAwesomeStuff();
61
Calum

Tôi ngạc nhiên khi không ai nhắc đến dự án lombok

Có, hiện tại không có thuộc tính nào trong Java. Có một số tính năng còn thiếu khác là tốt.
Nhưng may mắn thay, chúng tôi có dự án lombok đó đang cố gắng cải thiện tình hình. Nó cũng đang ngày càng phổ biến hơn mỗi ngày.

Vì vậy, nếu bạn đang sử dụng lombok:

@Getter @Setter int awesomeInteger = 5;

Mã này cũng sẽ tạo getAwesomeIntegersetAwesomeInteger. Vì vậy, nó khá giống với Thuộc tính tự động triển khai C # .

Bạn có thể nhận thêm thông tin về lettersk getters và setters tại đây .
Bạn chắc chắn nên kiểm tra các tính năng khác cũng như . Sở thích của tôi là: 

Lombok được tích hợp tốt với các IDE, vì vậy nó sẽ hiển thị các phương thức được tạo như nếu chúng tồn tại (đề xuất, nội dung lớp, đi đến khai báo và tái cấu trúc).
Vấn đề duy nhất với lombok là các lập trình viên khác có thể không biết về nó. Bạn luôn có thể delombok mã nhưng đó là một cách giải quyết hơn là một giải pháp.

31

"Hỗ trợ thuộc tính Java" đã được đề xuất cho Java 7, nhưng không biến nó thành ngôn ngữ.

Xem http://tech.puredanger.com/Java7#property để biết thêm liên kết và thông tin, nếu quan tâm.

6
Cheekysoft

Quy ước bean là viết mã như thế này:

private int foo;
public int getFoo() {
    return foo;
}
public void setFoo(int newFoo) {
    foo = newFoo;
}

Trong một số ngôn ngữ khác trên JVM, ví dụ: Groovy, bạn có được các thuộc tính có thể ghi đè tương tự như C #, ví dụ:

int foo

được truy cập với một .foo đơn giản và tận dụng các triển khai getFoosetFoo mặc định mà bạn có thể ghi đè khi cần thiết.

6
Hank Gay
public class Animal {

    @Getter @Setter private String name;
    @Getter @Setter private String gender;
    @Getter @Setter private String species;
}

Đây là một cái gì đó giống như thuộc tính C #. Đó là http://projectlombok.org/

6
dantuch

Bạn có thể không cần tiền tố "get" và "set", để làm cho nó trông giống các thuộc tính hơn, bạn có thể làm như thế này:

public class Person {
    private String firstName = "";
    private Integer age = 0;

    public String firstName() { return firstName; } // getter
    public void firstName(String val) { firstName = val; } // setter

    public Integer age() { return age; } // getter
    public void age(Integer val) { age = val; } //setter

    public static void main(String[] args) {
        Person p = new Person();

        //set
        p.firstName("Lemuel");
        p.age(40);

        //get
        System.out.println(String.format("I'm %s, %d yearsold",
            p.firstName(),
            p.age());
    }
}
4
LEMUEL ADANE

Từ Jeffrey Richter's book CLR qua C #: (Tôi nghĩ đây có thể là những lý do tại sao các thuộc tính vẫn không được thêm vào Java)

  • Một phương pháp tài sản có thể ném một ngoại lệ; truy cập trường không bao giờ ném một ngoại lệ.
  • Một thuộc tính không thể được truyền dưới dạng tham số out hoặc ref cho một phương thức; một lĩnh vực có thể.
  • Một phương thức thuộc tính có thể mất nhiều thời gian để thực thi; truy cập trường luôn hoàn thành ngay lập tức. Một lý do phổ biến để sử dụng các thuộc tính là để thực hiện đồng bộ hóa luồng, có thể dừng luồng mãi mãi và do đó, không nên sử dụng thuộc tính nếu cần đồng bộ hóa luồng. Trong tình huống đó, một phương pháp được ưa thích. Ngoài ra, nếu lớp của bạn có thể được truy cập từ xa (ví dụ: lớp của bạn có nguồn gốc từ System.MarshalByRefObject), việc gọi phương thức thuộc tính sẽ rất chậm, và do đó, một phương thức được ưu tiên cho một thuộc tính. Theo tôi, các lớp có nguồn gốc từ MarshalByRefObject không bao giờ nên sử dụng các thuộc tính.
  • Nếu được gọi nhiều lần liên tiếp, một phương thức thuộc tính có thể trả về một giá trị khác nhau mỗi lần; một trường trả về cùng một giá trị mỗi lần. Lớp System.DateTime có thuộc tính Now chỉ đọc trả về ngày và giờ hiện tại. Mỗi lần bạn truy vấn thuộc tính này, nó sẽ trả về một giá trị khác nhau. Đây là một sai lầm và Microsoft mong muốn rằng họ có thể sửa lớp bằng cách biến Now thành phương thức thay vì thuộc tính. Environment thuộc tính TickCount là một ví dụ khác về lỗi này.
  • Một phương pháp tài sản có thể gây ra tác dụng phụ có thể quan sát được; truy cập trường không bao giờ làm. Nói cách khác, người dùng của một loại sẽ có thể đặt các thuộc tính khác nhau được xác định bởi một loại theo bất kỳ thứ tự nào họ chọn mà không nhận thấy bất kỳ hành vi khác nhau trong loại.
  • Một phương thức thuộc tính có thể yêu cầu bộ nhớ bổ sung hoặc trả về một tham chiếu đến một cái gì đó không thực sự là một phần của trạng thái đối tượng, do đó sửa đổi đối tượng được trả về không có tác dụng đối với đối tượng ban đầu; truy vấn một trường luôn trả về một tham chiếu đến một đối tượng được đảm bảo là một phần của trạng thái ban đầu của đối tượng. Làm việc với một thuộc tính trả về một bản sao có thể rất khó hiểu đối với các nhà phát triển và đặc điểm này thường không được ghi lại.
3
th1rdey3

Hầu hết các IDE cho Java sẽ tự động tạo mã getter và setter cho bạn nếu bạn muốn chúng. Có một số quy ước khác nhau và IDE như Eclipse sẽ cho phép bạn chọn cái nào bạn muốn sử dụng và thậm chí cho phép bạn xác định cái của riêng mình.

Eclipse thậm chí bao gồm tái cấu trúc tự động sẽ cho phép bạn bọc một thuộc tính trong getter và setter và nó sẽ sửa đổi tất cả mã truy cập trực tiếp vào thuộc tính, để làm cho nó sử dụng getter và/hoặc setter.

Tất nhiên, Eclipse chỉ có thể sửa đổi mã mà nó biết - bất kỳ phụ thuộc bên ngoài nào bạn có thể bị phá vỡ bằng cách tái cấu trúc như vậy.

3
Bill Michell

Trải nghiệm Java của tôi cũng không cao, vì vậy bất cứ ai cũng cảm thấy thoải mái khi sửa tôi. Nhưng AFAIK, quy ước chung là viết hai phương thức như vậy:

public string getMyString() {
    // return it here
}

public void setMyString(string myString) {
    // set it here
}
2
Mark Embling

Tôi chỉ phát hành các chú thích Java 5/6 và một bộ xử lý chú thích để giúp điều này.

Hãy xem http://code.google.com.vn/p/javadude/wiki/Annotations

Tài liệu này hơi nhẹ ngay bây giờ, nhưng quickref sẽ có ý tưởng xuyên suốt.

Về cơ bản, nó tạo ra một siêu lớp với các getters/setters (và nhiều tùy chọn tạo mã khác).

Một lớp mẫu có thể trông giống như

@Bean(properties = {
    @Property(name="name", bound=true),
    @Property(name="age,type=int.class)
})
public class Person extends PersonGen {
}

Có rất nhiều mẫu có sẵn và không có phụ thuộc thời gian chạy trong mã được tạo.

Gửi cho tôi một email nếu bạn dùng thử và thấy nó hữu ích! -- Scott

1
Scott Stanchfield

Nếu bạn đang sử dụng Eclipse thì nó có khả năng tự động tạo phương thức getter và setter cho các thuộc tính bên trong, nó có thể là một công cụ hữu ích và tiết kiệm thời gian.

1
TK.

Không có từ khóa thuộc tính trong Java (như bạn có thể tìm thấy nó trong C #) cách gần nhất để có 1 Word getter/setter là làm như trong C++:

public class MyClass
{
    private int aMyAttribute;
    public MyClass()
    {
        this.aMyAttribute = 0;
    }
    public void mMyAttribute(int pMyAttributeParameter)
    {
        this.aMyAttribute = pMyAttributeParameter;
    }
    public int mMyAttribute()
    {
        return this.aMyAttribute;
    }
}
//usage :
int vIndex = 1;
MyClass vClass = new MyClass();
vClass.mMyAttribute(vIndex);
vIndex = 0;
vIndex = vClass.mMyAttribute();
// vIndex == 1
1
Patrick PIGNOL

Như đã đề cập trước đây cho Eclipse, môi trường phát triển tích hợp (IDE) thường có thể tự động tạo các phương thức truy cập.

Bạn cũng có thể làm điều đó bằng NetBeans. 

Để tạo các phương thức truy cập cho lớp của bạn, hãy mở tệp lớp, sau đó bấm chuột phải vào bất cứ nơi nào trong trình chỉnh sửa mã nguồn và chọn lệnh menu Refactor, Encapsulation Field. Một hộp thoại mở ra. Nhấp vào Chọn tất cả, sau đó nhấp vào Refactor . Voilà,

Chúc may mắn,

0
levteck