CharSequence
= giao diện
String
= thực hiện cụ thể
Bạn đã nói:
chuyển đổi từ cái này sang cái khác
Không có chuyển đổi từ String
.
- Mọi
String
đối tượng là một CharSequence
.
- Mỗi
CharSequence
có thể sản xuất a String
. Gọi CharSequence::toString
. Nếu CharSequence
xảy ra là a String
, thì phương thức trả về một tham chiếu đến đối tượng của chính nó.
Nói cách khác, mỗi String
là một CharSequence
, nhưng không phải mọi CharSequence
là một String
.
Lập trình đến một giao diện
Lập trình trong Android, hầu hết các giá trị văn bản được mong đợi trong CharSequence.
Tại sao vậy? Lợi ích là gì và tác động chính của việc sử dụng CharSequence trên String là gì?
Nói chung, lập trình cho một giao diện tốt hơn so với lập trình cho các lớp cụ thể. Điều này mang lại sự linh hoạt, vì vậy chúng ta có thể chuyển đổi giữa các triển khai cụ thể của một giao diện cụ thể mà không vi phạm mã khác.
Khi phát triển API được sử dụng bởi các lập trình viên khác nhau trong các tình huống khác nhau, hãy viết mã của bạn để đưa ra và lấy các giao diện chung nhất có thể. Điều này cho phép lập trình viên gọi tự do sử dụng các triển khai khác nhau của giao diện đó, bất kỳ triển khai nào là tốt nhất cho bối cảnh cụ thể của họ.
Ví dụ, nhìn vào Khung sưu tập Java . Nếu API của bạn cung cấp cho hoặc mất một bộ sưu tập lệnh của các đối tượng, kê khai các phương pháp của bạn như sử dụng List
chứ không phải là ArrayList
, LinkedList
hoặc bất kỳ thực hiện của bên thứ 3 khác List
.
Khi viết một phương thức nhỏ nhanh và bẩn chỉ được sử dụng bởi mã của bạn ở một nơi cụ thể, trái ngược với việc viết API được sử dụng ở nhiều nơi, bạn không cần phải sử dụng giao diện chung chung hơn là cụ thể lớp học. Nhưng ngay cả khi đó, thật đau lòng khi sử dụng giao diện chung nhất mà bạn có thể.
Sự khác biệt chính là gì và những vấn đề được mong đợi, trong khi sử dụng chúng,
- Với một
String
bạn biết bạn có một đoạn văn bản duy nhất, hoàn toàn trong bộ nhớ và là bất biến.
- Với một
CharSequence
, bạn không biết các tính năng cụ thể của việc triển khai cụ thể có thể là gì.
Đối CharSequence
tượng có thể đại diện cho một đoạn văn bản khổng lồ, và do đó có ý nghĩa bộ nhớ. Hoặc có thể nhiều đoạn văn bản được theo dõi riêng sẽ cần được ghép lại với nhau khi bạn gọi toString
, và do đó có vấn đề về hiệu suất. Việc triển khai thậm chí có thể lấy văn bản từ một dịch vụ từ xa và do đó có ý nghĩa về độ trễ.
và chuyển đổi từ cái này sang cái khác?
Bạn thường sẽ không được chuyển đổi qua lại. A String
là một CharSequence
. Nếu phương thức của bạn tuyên bố rằng nó cần một CharSequence
, lập trình viên gọi có thể truyền một String
đối tượng hoặc có thể truyền một cái gì đó khác như a StringBuffer
hoặc StringBuilder
. Mã phương thức của bạn sẽ đơn giản sử dụng bất cứ thứ gì được thông qua, gọi bất kỳ CharSequence
phương thức nào.
Cách gần nhất bạn có thể chuyển đổi là nếu mã của bạn nhận được a CharSequence
và bạn biết bạn cần a String
. Có lẽ bạn đang giao tiếp với mã cũ được viết cho String
lớp chứ không phải được ghi vào CharSequence
giao diện. Hoặc có lẽ mã của bạn sẽ làm việc mạnh mẽ với văn bản, chẳng hạn như lặp đi lặp lại hoặc phân tích. Trong trường hợp đó, bạn muốn thực hiện bất kỳ hiệu suất có thể đạt được chỉ một lần, vì vậy bạn gọitoString
lên trước. Sau đó tiến hành công việc của bạn bằng cách sử dụng những gì bạn biết là một đoạn văn bản hoàn toàn trong bộ nhớ.
Lịch sử xoắn
Lưu ý các ý kiến được thực hiện trên câu trả lời được chấp nhận . Các CharSequence
giao diện đã được trang bị thêm vào cấu trúc lớp học hiện có, vì vậy có một số tinh tế quan trọng ( equals()
& hashCode()
). Lưu ý các phiên bản khác nhau của Java (1, 2, 4 & 5) được gắn thẻ trên các lớp / giao diện. Lý tưởng nhất CharSequence
đã có được ngay từ đầu, nhưng đó là cuộc sống.
Sơ đồ lớp của tôi dưới đây có thể giúp bạn thấy bức tranh lớn về các loại chuỗi trong Java 7/8. Tôi không chắc liệu tất cả những thứ này có trong Android hay không, nhưng bối cảnh chung vẫn có thể hữu ích với bạn.