Có sai không khi sử dụng các phương thức hoặc các lớp không dùng trong Java?


153

Tôi đang sử dụng nhật thực để phát triển một ứng dụng web. Mới hôm nay tôi đã cập nhật phiên bản struts của mình bằng cách thay đổi tệp JAR. Tôi đang nhận được cảnh báo ở một số nơi rằng các phương thức không được dùng nữa, nhưng mã đang hoạt động tốt.

Tôi muốn biết một số điều

  1. Có sai không khi sử dụng các phương thức hoặc các lớp không dùng trong Java?

  2. Điều gì xảy ra nếu tôi không thay đổi bất kỳ phương pháp nào và chạy ứng dụng của mình với các cảnh báo mà tôi có, liệu nó có tạo ra bất kỳ vấn đề nào về hiệu suất không.


7
Bạn có 'tiếp tục' lái xe 1955 Volkswagen Beetlengay cả khi bạn được cung cấp Corvette Stingraymiễn phí không? (0:
KMån

75
@Kman bạn đang so sánh một chiếc xe châu Âu với một chiếc xe Mỹ?;)
ponzao

2
@Ponzao và 4những người khác: Gotcha! (0;
KMån

2
Sai lầm? Có phải chúng ta đang nói chuyện phàm tục hay chỉ là sự suy giảm tĩnh mạch ở đây?
FastAl

5
@Alexander không có phiếu bầu cho bình luận của bạn, vì vậy +1 cho bình luận của bạn cũng vậy;) trong mọi trường hợp, chắc chắn rằng mã mới tốt hơn 1000 so với mã cũ. Sự so sánh sẽ tốt hơn giữa 1955 Volkswagen Beetle1956 Volkswagen Beetlevới lốp xe mới mà bạn không biết khi nào sẽ phá vỡ!
Aleks

Câu trả lời:


265

1. Có sai không khi sử dụng các phương thức hoặc các lớp không dùng trong Java?

Từ định nghĩa của deprecated :

Một phần tử chương trình được chú thích @Deprecated là phần tử mà các lập trình viên không khuyến khích sử dụng, thường là vì nó nguy hiểm hoặc vì có một sự thay thế tốt hơn.

Phương thức này được giữ trong API để tương thích ngược trong một khoảng thời gian không xác định và có thể trong các bản phát hành trong tương lai sẽ bị xóa. Đó là, không, nó không sai , nhưng có một cách tốt hơn để làm điều đó, mạnh mẽ hơn đối với các thay đổi API.

2. Điều gì sẽ xảy ra nếu tôi không thay đổi bất kỳ phương thức nào và chạy ứng dụng của mình với các cảnh báo mà tôi có, liệu nó có tạo ra bất kỳ vấn đề nào về hiệu suất không.

Nhiều khả năng là không. Nó sẽ tiếp tục hoạt động như trước khi khấu hao. Hợp đồng của phương thức API sẽ không thay đổi. Nếu một số cấu trúc dữ liệu nội bộ thay đổi theo hướng có phương pháp mới, tốt hơn, có thể có tác động về hiệu suất, nhưng điều đó rất khó xảy ra.


Sự phản đối hài hước nhất trong API Java, là imo , FontMetrics.getMaxDecent. Lý do phản đối: Lỗi chính tả.

Không dùng nữa Kể từ phiên bản JDK 1.1.1, được thay thế bằng getMaxDescent ().


5
Sự phản đối hài hước tiếp theo trong API Java sẽ được đặtMultiClickThreshkeep (int threshkeep) và getMultiClickTreshkeep () trong AbstractButton (Swing). Hãy sẵn sàng cho hai điều đó! ;)
JavaT kỹ thuật

3
Chúng ta cần phải làm điều này với HTTP REAXER. Thật điên rồ: vi.wikipedia.org/wiki/HTTP_Vferer
kmiklas

1
@DaveMcClelland, làm cho nó 70 từ 69: D;)
VdeX

28

Bạn vẫn có thể sử dụng mã không dùng nữa mà không thay đổi hiệu năng, nhưng toàn bộ quan điểm không tán thành một phương thức / lớp là cho người dùng biết bây giờ có cách sử dụng mã tốt hơn và trong bản phát hành trong tương lai, mã không dùng nữa có thể bị xóa.


1
Làm thế nào bạn có thể chắc chắn rằng nó không có thay đổi trong hiệu suất? Các deprication có thể ví dụ là do sự thay đổi của một cấu trúc dữ liệu nội bộ, nói từ một HashSet đến một TreeSet, ví dụ.
aioobe

@aioobe - Theo hiểu biết của tôi, OP đã hỏi liệu việc gọi mã không dùng có vấn đề về hiệu năng hay không, điều đó không cho rằng nó không thay đổi mã byte được tạo ra (trước 1.5 là trong javadoc, bây giờ chú thích đang được sử dụng, nhưng vẫn không thay đổi hiệu suất)
abyx

Khi đi từ một phiên bản của thư viện, sang một phiên bản khác, không có gì đảm bảo rằng mã byte của một phương thức trong phiên bản mới giống hệt với mã byte của cùng một phương thức trong phiên bản trước.
aioobe

@aioobe - có một đảm bảo rằng chỉ cần làm cho nó không được dùng nữa sẽ không thay đổi mã byte, đó là điều tôi nghĩ OP có nghĩa. Tất nhiên mã tự thay đổi, đó là lý do tại sao chúng tôi không dùng mã.
abyx

Nếu bạn tiếp tục sử dụng phiên bản giống như trước đây, không có thay đổi. Nhưng nếu bạn sử dụng một phiên bản mới hơn của thư viện và họ không phản đối API, thì COULD sẽ là một sự thay đổi về hiệu suất, nếu việc triển khai cơ bản bị thay đổi mạnh mẽ và API mới tận dụng lợi thế của nó, trong khi API cũ không như hiệu quả như trước đây, chống lại cấu trúc mới hơn này.
gregturn

21

Thuật ngữ

Từ thuật ngữ chính thức của Mặt trời:

deprecation : Đề cập đến một lớp, giao diện, hàm tạo, phương thức hoặc trường không còn được khuyến nghị và có thể ngừng tồn tại trong phiên bản tương lai.

Từ hướng dẫn cách thức và thời điểm không dùng nữa:

Bạn có thể đã nghe cụm từ "hài hước tự ti" hoặc hài hước làm giảm thiểu tầm quan trọng của người nói. Một lớp hoặc phương thức không dùng nữa là như thế. Nó không còn quan trọng nữa. Trên thực tế, nó không quan trọng đến mức bạn không nên sử dụng nó nữa, vì nó đã được thay thế và có thể ngừng tồn tại trong tương lai.

Các @Deprecatedchú thích đi một bước xa hơn và cảnh báo nguy hiểm:

Một phần tử chương trình được chú thích @Deprecatedlà một phần mà các lập trình viên không khuyến khích sử dụng, thường là vì nó nguy hiểm hoặc vì một sự thay thế tốt hơn tồn tại.

Người giới thiệu


Đúng hay sai?

Câu hỏi liệu sử dụng các phương pháp không dùng đúng hay sai sẽ phải được kiểm tra trên cơ sở cá nhân. Dưới đây là TẤT CẢ các trích dẫn mà từ "không dùng nữa" xuất hiện trong Ấn bản Java hiệu quả thứ 2 :

Mục 7: Tránh các công cụ quyết toán : Các phương pháp duy nhất tuyên bố đảm bảo quyết toán là System.runFinalizersOnExitvà kết nghĩa xấu xa của nóRuntime.runFinalizersOnExit . Những phương pháp này rất thiếu sót và đã bị phản đối.

Mục 66: Đồng bộ hóa quyền truy cập vào dữ liệu có thể thay đổi được chia sẻ : Các thư viện cung cấp Thread.stopphương thức, nhưng phương thức này không được chấp nhận từ lâu vì nó vốn không an toàn - việc sử dụng nó có thể dẫn đến hỏng dữ liệu.

Mục 70: An toàn luồng tài liệu :System.runFinalizersOnExit Phương thức này là luồng thù địch và không được dùng nữa.

Mục 73: Tránh các nhóm luồng : Chúng cho phép bạn áp dụng một số Threadnguyên thủy nhất định cho một loạt các luồng cùng một lúc. Một vài trong số những người nguyên thủy này đã không được chấp nhận và phần còn lại được sử dụng không thường xuyên. [...] Các nhóm chủ đề đã lỗi thời.

Vì vậy, ít nhất là với tất cả các phương pháp trên, rõ ràng là sai khi sử dụng chúng, ít nhất là theo Josh Bloch.

Với các phương pháp khác, bạn phải xem xét các vấn đề một cách riêng lẻ và hiểu TẠI SAO chúng bị phản đối, nhưng nói chung, khi quyết định phản đối là hợp lý, nó sẽ có xu hướng nghiêng về sai hơn là tiếp tục sử dụng chúng.

Câu hỏi liên quan


3
"Không dùng nữa" là từ "de" + "preare" trong tiếng Latin có nghĩa là "cầu nguyện chống lại". Khi một cái gì đó được mô tả là không dùng nữa, một Tiêu chuẩn đang cầu nguyện - cầu xin - bạn không sử dụng nó; đó là một cảnh báo rằng nó có thể bị xóa trong phiên bản tương lai của Tiêu chuẩn đó. Lưu ý rằng một tính năng không dùng nữa được yêu cầu phải được thực hiện đầy đủ trong mọi triển khai của phiên bản hiện tại của Tiêu chuẩn đó. Mặc dù vậy, việc bạn đề cập đến sự hài hước tự ti là hơi lạc lõng; "Tự ti" theo nghĩa đó là một sự tham nhũng của "tự ti", có nguồn gốc và ý nghĩa khác nhau.
dajames

17

Ngoài tất cả các phản hồi xuất sắc ở trên, tôi thấy có một lý do khác để loại bỏ các lệnh gọi API không dùng nữa.

Nghiên cứu lý do tại sao một cuộc gọi không được chấp nhận Tôi thường thấy mình học được những điều thú vị về Java / API / Framework. Thường có một lý do chính đáng tại sao một phương pháp đang bị phản đối và hiểu những lý do này dẫn đến những hiểu biết sâu sắc hơn.

Vì vậy, từ góc độ học tập / phát triển, nó cũng là một nỗ lực đáng giá


11

Nó chắc chắn không tạo ra vấn đề về hiệu năng - nghĩa là không dùng nữa trong tương lai, có khả năng chức năng đó sẽ không còn là một phần của thư viện nữa, vì vậy bạn nên tránh sử dụng nó trong mã mới và thay đổi mã cũ để ngừng sử dụng nó, vì vậy một ngày nào đó bạn không gặp vấn đề gì khi nâng cấp thanh chống và thấy rằng chức năng đó không còn nữa


1
Đánh giá từ kinh nghiệm, "không dùng nữa" thực sự có nghĩa là "bạn không nên sử dụng cái này nữa, nhưng nó sẽ có sẵn mãi mãi." Ít nhất là đối với API tiêu chuẩn Java, tôi không biết bất kỳ phương thức hoặc lớp nào thực sự bị xóa sau khi bị phản đối.
Michael Borgwardt

1
@Michael Vâng, trong thực tế, API hiếm khi loại bỏ các hàm không dùng nữa vì chúng có thể bị phản đối trong mười năm với các trình biên dịch xuất ra "CẢNH BÁO: DỪNG SỬ DỤNG BÓNG ĐÁ NÀY", và mọi người vẫn sẽ bỏ qua ngày cuối cùng họ gỡ bỏ nó. Tôi nghĩ rằng sự phản đối được cho là có nghĩa là "một ngày nào đó chúng tôi muốn loại bỏ điều này, vì vậy xin vui lòng ngừng sử dụng nó", ngay cả khi trong thực tế, điều đó hiếm khi thực sự xảy ra
Michael Mrozek

@Michael Mrozek: Không đồng ý với tuyên bố It certainly doesn't create a performance issue; nó quá chủ quan để nói rằng
KMån

1
@KMan Một chức năng được đánh dấu là không dùng nữa bằng cách nào đó làm cho nó kém hiệu quả hơn trước khi được đánh dấu - nó sẽ chạy chính xác như trước
Michael Mrozek

@Michael Borgwardt: Đó là cách nó hoạt động trong hầu hết các ngôn ngữ được tiêu chuẩn hóa. Và, tất nhiên, nếu bất cứ điều gì không được chấp nhận sẽ bị xóa khỏi tiêu chuẩn, các triển khai phổ biến sẽ giữ nó như một phần mở rộng.
David Thornley

8

Điều đó không sai, chỉ là không nên. Nó thường có nghĩa là tại thời điểm này có một cách tốt hơn để làm mọi thứ và bạn sẽ làm tốt nếu bạn sử dụng cách cải tiến mới. Một số thứ không dùng nữa thực sự nguy hiểm và nên tránh hoàn toàn. Cách mới có thể mang lại hiệu suất tốt hơn so với cách không dùng nữa, nhưng không phải lúc nào cũng như vậy.


8

Bạn có thể đã nghe thấy thuật ngữ "hài hước tự ti". Đó là sự hài hước làm giảm thiểu tầm quan trọng của bạn. Một lớp hoặc phương thức không dùng nữa là như thế. Nó không còn quan trọng nữa. Trên thực tế, nó không quan trọng đến mức nó không còn được sử dụng nữa, vì có lẽ nó sẽ không còn tồn tại trong tương lai.

Cố gắng tránh nó


4
  1. Nói chung là không, hoàn toàn không sai khi sử dụng deprecatedcác phương thức miễn là bạn có kế hoạch dự phòng tốt để tránh mọi vấn đề nếu / khi các phương thức đó biến mất khỏi thư viện bạn đang sử dụng. Với chính API Java, điều này không bao giờ xảy ra nhưng với bất kỳ điều gì khác, điều đó có nghĩa là nó sẽ bị xóa. Nếu bạn đặc biệt có kế hoạch không nâng cấp ( mặc dù về lâu dài rất có thể bạn nên ) các thư viện hỗ trợ phần mềm của bạn thì không có vấn đề gì trong việc sử dụngdeprecated các phương thức.
  2. Không.

3

Vâng, đó là sai.

Các phương thức hoặc lớp không dùng nữa sẽ bị xóa trong các phiên bản Java trong tương lai và không nên được sử dụng. Trong mỗi trường hợp, nên có một sự thay thế có sẵn. Sử dụng nó.

Có một vài trường hợp khi bạn phải sử dụng một lớp hoặc phương thức không dùng nữa để đáp ứng mục tiêu dự án. Trong trường hợp này, bạn thực sự không có lựa chọn nào khác ngoài việc sử dụng nó. Các phiên bản Java trong tương lai có thể phá vỡ mã đó, nhưng nếu đó là một yêu cầu bạn phải sống với điều đó. Đây có lẽ không phải là lần đầu tiên bạn phải làm điều gì đó sai để đáp ứng yêu cầu của dự án và chắc chắn đây sẽ không phải là lần cuối cùng.

Khi bạn nâng cấp lên phiên bản Java mới hoặc một số thư viện khác, đôi khi một phương thức hoặc một lớp bạn đang sử dụng trở nên không dùng nữa. Các phương pháp không dùng nữa không được hỗ trợ, nhưng không nên tạo ra kết quả bất ngờ. Tuy nhiên, điều đó không có nghĩa là họ sẽ không chuyển mã ASAP.

Quá trình phản đối là có để đảm bảo rằng các tác giả có đủ thời gian để thay đổi mã của họ từ API cũ sang API mới. Hãy sử dụng thời gian này. Thay đổi mã của bạn qua ASAP.


2

Điều đó không sai, nhưng một số phương pháp không dùng nữa được loại bỏ trong các phiên bản tương lai của phần mềm, do đó bạn có thể sẽ không có mã làm việc.


Removed? Xem định nghĩa stackoverflow.com/questions/2941900/
hàn

1
@KMan - trong liên kết bạn đã đăng, nó được viết - "Phương thức được giữ trong API để tương thích ngược trong một khoảng thời gian không xác định và có thể trong các bản phát hành trong tương lai sẽ bị xóa." Tôi đã viết như vậy - một số phương pháp không dùng nữa có thể được loại bỏ trong tương lai gần hoặc xa.
Petar Minchev

2

Có sai không khi sử dụng các phương thức hoặc các lớp không dùng trong Java? "

Không sai như vậy nhưng nó có thể giúp bạn tiết kiệm một số rắc rối. Dưới đây là một ví dụ về việc không khuyến khích sử dụng phương pháp không dùng nữa:

http://java.sun.com/j2se/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html

Tại sao Thread.stop không được dùng nữa?

Bởi vì nó vốn không an toàn. Dừng một chuỗi khiến nó mở khóa tất cả các màn hình mà nó đã khóa. (Các màn hình được mở khóa khi ngoại lệ ThreadDeath truyền lên ngăn xếp.) Nếu bất kỳ đối tượng nào trước đây được bảo vệ bởi các màn hình này ở trạng thái không nhất quán, các luồng khác có thể xem các đối tượng này ở trạng thái không nhất quán. Những đồ vật như vậy được cho là bị hư hại. Khi các luồng hoạt động trên các đối tượng bị hư hỏng, hành vi tùy ý có thể dẫn đến. Hành vi này có thể tinh tế và khó phát hiện, hoặc nó có thể được phát âm. Không giống như các ngoại lệ không được kiểm tra khác, ThreadDeath giết chết các chủ đề một cách im lặng; do đó, người dùng không có cảnh báo rằng chương trình của mình có thể bị hỏng. Tham nhũng có thể tự biểu hiện bất cứ lúc nào sau khi thiệt hại thực tế xảy ra, thậm chí là vài giờ hoặc vài ngày trong tương lai.


Điều gì xảy ra nếu không thay đổi bất kỳ phương thức nào và chạy ứng dụng của tôi với các cảnh báo mà tôi có, liệu nó có tạo ra bất kỳ vấn đề nào về hiệu suất không.

Không nên có vấn đề về hiệu suất. API tiêu chuẩn được thiết kế để tôn trọng một số khả năng tương thích ngược để các ứng dụng có thể dần dần thích nghi với các phiên bản Java mới hơn.


2

Có sai không khi sử dụng các phương thức hoặc các lớp không dùng trong Java? Nó không "sai", vẫn hoạt động nhưng tránh nó càng nhiều càng tốt.

Giả sử có một lỗ hổng bảo mật liên quan đến một phương thức và các nhà phát triển xác định rằng đó là một lỗ hổng thiết kế. Vì vậy, họ có thể quyết định từ chối phương pháp và giới thiệu cách mới.

Vì vậy, nếu bạn vẫn sử dụng phương pháp cũ, bạn có một mối đe dọa. Vì vậy, hãy nhận biết lý do cho sự phản đối và kiểm tra xem nó ảnh hưởng đến bạn như thế nào.

Điều gì xảy ra nếu không thay đổi bất kỳ phương thức nào và chạy ứng dụng của tôi với các cảnh báo mà tôi có, liệu nó có tạo ra bất kỳ vấn đề nào về hiệu suất không.

Nếu sự phản đối là do vấn đề hiệu suất, thì bạn sẽ gặp vấn đề về hiệu suất, nếu không thì không có lý do gì để có vấn đề như vậy. Một lần nữa muốn chỉ ra, nhận thức được lý do để phản đối.


2

Trong Java, @Deprecated, trong C # là [Lỗi thời].

Tôi nghĩ rằng tôi thích thuật ngữ của C #. Nó chỉ có nghĩa là nó đã lỗi thời. Bạn vẫn có thể sử dụng nó nếu bạn muốn, nhưng có lẽ có một cách tốt hơn.

Giống như sử dụng Windows 3.1 thay vì Windows 7 nếu bạn tin rằng Windows 3.1 đã lỗi thời. Bạn vẫn có thể sử dụng nó, nhưng có thể có các tính năng tốt hơn trong phiên bản tương lai, cộng với các phiên bản trong tương lai có thể sẽ được hỗ trợ - phiên bản lỗi thời sẽ không có.

Tương tự đối với @Deprecated của Java - bạn vẫn có thể sử dụng phương thức này, nhưng tự chịu rủi ro - trong tương lai, nó có thể có các lựa chọn thay thế tốt hơn và thậm chí có thể không được hỗ trợ.

Nếu bạn đang sử dụng mã không dùng nữa, điều đó thường ổn, miễn là bạn không phải nâng cấp lên API mới hơn - mã không dùng nữa có thể không tồn tại ở đó. Tôi đề nghị nếu bạn thấy một cái gì đó đang sử dụng mã không dùng nữa, để cập nhật để sử dụng các lựa chọn thay thế mới hơn (điều này thường được chỉ ra trên chú thích hoặc trong một bình luận không tán thành Javadoc).

Chỉnh sửa: Và như Michael đã chỉ ra, nếu lý do phản đối là do lỗ hổng trong chức năng (hoặc vì chức năng thậm chí không tồn tại), thì rõ ràng, người ta không nên sử dụng mã không dùng nữa.


1
"Nếu bạn đang sử dụng mã không được chấp nhận, thì tốt, miễn là bạn không phải nâng cấp lên API mới hơn" - không hoàn toàn. Hãy xem tại sao Thread.stop () không được dùng nữa và bạn sẽ thấy rằng nó không ổn, trong bất kỳ phiên bản JRE nào.
Michael

Ok, tôi nên nói "thường" tốt (sẽ cập nhật bit đó) :) Do đó, hãy tự chịu rủi ro khi sử dụng. Rõ ràng, nếu lý do từ chối nó là để ngăn chặn một lỗ hổng trong chức năng của nó, thì không nên sử dụng nó. Nói chung, mặc dù sử dụng một phương pháp không dùng nữa. Vì vậy, ja, tất cả phụ thuộc vào lý do khấu hao. Thật.
jamiebarrow

1

Tất nhiên là không - vì toàn bộ Java đang bị @Deprecated :-) bạn có thể thoải mái sử dụng chúng miễn là Java tồn tại lâu. Dù sao cũng sẽ không nhận thấy bất kỳ sự khác biệt nào, trừ khi nó thực sự bị hỏng. Ý nghĩa - phải đọc về nó và sau đó quyết định.

Tuy nhiên, trong .Net, khi một cái gì đó được tuyên bố là [Lỗi thời], hãy đọc và đọc ngay lập tức ngay cả khi bạn chưa từng sử dụng nó trước đây - bạn có khoảng 50% khả năng nó hiệu quả hơn và / hoặc dễ sử dụng hơn thay thế :-))

Vì vậy, nói chung, có thể khá có lợi khi bảo thủ kỹ thuật trong những ngày này, nhưng bạn phải làm việc đọc trước.


1

Tôi cảm thấy rằng phương pháp không dùng nữa có nghĩa là; có sẵn một phương thức thay thế = ive tốt hơn về mọi mặt so với phương thức hiện có. Tốt hơn để sử dụng phương pháp tốt hơn phương pháp cũ hiện có. Để tương thích ngược, các phương thức cũ bị bỏ lại.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.