tại sao "Integer [] x = (Integer []) new Object[100]; " biên dịch?
In lạiTác giả: trợ lý lỗiThời gian cập nhật: 26-10-2023 20:14:03274
Tôi biên soạn:
Tôi đã viết:
Số nguyên [ ] x = (Số nguyên [ ]) đối tượng mới [100];
nó thành công. và tôi không biết tại sao?
Nó đã hoạt động. Tôi không biết tại sao?
Thêm câu trả lời
Bởi vì bạn đã nói dối trình biên dịch.
Bởi vì bạn đã nói dối trình biên dịch.
Casting là một tiện ích mà Java cung cấp cho bạn để khiến trình biên dịch Java tin tưởng bạn. Vì vậy, nó biên dịch nhưng bạn đang cố gắng lạm dụng sự tiện lợi được cung cấp cho bạn. Hãy nhớ Nghiệp chướng 😊
Truyền là một tiện ích do Java cung cấp để làm cho trình biên dịch Java tin cậy bạn. Vì vậy, nó biên dịch, nhưng bạn đang cố gắng lạm dụng sự tiện lợi mang lại cho bạn. Bạn có nhớ Karma không?
Lưu ý rằng việc ép kiểu biểu thức theo nghĩa đen xảy ra tại thời điểm biên dịch: số nguyên i = (int)(1.0+2.0); Điều này khác với việc ép kiểu tham chiếu như OP đã làm. Vì vậy, OP có thể đang hỏi tại sao kiểu tham chiếu lại khác với kiểu theo nghĩa đen.
Lưu ý rằng việc truyền các biểu thức bằng chữ xảy ra tại thời điểm biên dịch: int i=(Int)(1.0+2.0); điều này khác với việc truyền các kiểu tham chiếu như OP. Vì vậy OP có thể hỏi tại sao loại tham chiếu lại khác với loại văn bản.
Khuyến nghị câu trả lời tuyệt vời
Nó biên soạn. Nhưng nó không chạy. Hãy thử xem - nhét nó vào chủ yếu phương thức và thực thi nó. Bạn sẽ nhận được ClassCastException.
Nó sẽ biên dịch. Nhưng nó không hoạt động. Hãy thử - đặt nó vào phương thức Main và thực thi. Bạn sẽ nhận được ClassCastException.
Có một số thứ đang diễn ra ở đây. Hầu hết trong số này là 'khảo cổ ngôn ngữ lập trình' - không có gì có ý nghĩa và không có gì đặc biệt nhất quán. Nếu mục tiêu của bạn là học ngôn ngữ tốt hơn, có một quy tắc rất đơn giản mà bạn nên áp dụng cho lập trình java của mình:
Có rất nhiều điều đang diễn ra ở đây. Phần lớn trong số đó là "khảo cổ học ngôn ngữ lập trình" - không có cái nào có ý nghĩa và không có cái nào đặc biệt nhất quán. Nếu mục tiêu của bạn là học ngôn ngữ tốt hơn thì có một quy tắc rất đơn giản nên áp dụng cho việc lập trình Java của bạn:
Không sử dụng mảng. Hoàn toàn không. Cho bất cứ điều gì. Ngoại trừ có lẽ mảng của các kiểu nguyên thủy (số nguyên[], dài[], v.v.) vì lý do hiệu suất. Chúng không có ý nghĩa gì. Chúng không nhanh hơn danh sách và có đủ loại nhược điểm kỳ quặc. Bao gồm cả việc triển khai equals và hashCode và toString bị hỏng hiệu quả (ở chỗ chúng thực hiện những điều không mong muốn; đặc tả giải thích rõ ràng những điều này, nhưng một API thực hiện những gì đặc tả nói, nhưng đặc tả lại nói những điều không mong muốn kỳ lạ, thì tôi sẽ để người đọc nghĩ ra một thuật ngữ cho nó. Tôi tin rằng đó sẽ không phải là một thuật ngữ hay), chúng là sự kết hợp vô dụng của bất biến (chúng không thể phát triển hoặc thu hẹp) nhưng không thực sự bất biến (bạn có thể đặt giá trị), v.v.
Khi ép kiểu mảng, hãy giả sử trình biên dịch không biết gì và bạn sẽ phải dựa vào các ngoại lệ thời gian chạy. Thực sự, khi bạn đã đạt đến cấp độ này (Bạn đang ép kiểu mảng), bạn cần sao lưu và sửa bất cứ điều gì khiến bạn gặp rắc rối.
Thực sự không có nhiều ý nghĩa khi đi xa hơn nữa nếu mục tiêu của bạn là trở thành một lập trình viên Java giỏi.
Nếu mục tiêu của bạn là trở thành một lập trình viên Java giỏi thì không cần phải tiến xa hơn nữa.
Nhưng này, bạn đã hỏi - vậy thì, chúng ta hãy đội chiếc mũ nâu, cầm roi da, bật bài hát chủ đề của Indiana Jones và cùng khám phá sâu vào quá khứ xa xôi của Java nhé!
Nhưng này, bạn đã yêu cầu - vậy hãy đội mũ nâu, cầm roi, chơi bài hát chủ đề Indiana Jones và khám phá chiều sâu về quá khứ xa xôi của Java!
Hiệp phương sai, Phản phương sai, Bất biến.
Trước tiên, chúng ta cần giải quyết vấn đề chính. Một câu trả lời đã được đăng bởi một người không hiểu hệ thống kiểu, vì vậy, đó là bằng chứng giai thoại cho thấy điều này cần được giải thích trước.
Chúng ta cần giải quyết những vấn đề chính trước tiên. Ai đó không hiểu hệ thống loại đã đăng câu trả lời, vì vậy đây là bằng chứng giai thoại cần được giải thích trước.
Hệ thống kiểu của Java tự nó là 'đồng biến'. Điều đó có nghĩa là: Bất kỳ kiểu nào cũng là sự thay thế tốt cho bất kỳ siêu kiểu nào của nó. Nếu bạn có một phương thức yêu cầu bạn phải truyền cho nó một Con số tham số, bạn có thể truyền một biểu thức có kiểu Số nguyên, Không vấn đề.
Bản thân hệ thống kiểu của Java là "hiệp biến". Điều này có nghĩa: bất kỳ loại nào cũng có thể thay thế tốt cho bất kỳ siêu kiểu nào của nó. Nếu bạn có một phương thức yêu cầu truyền tham số Số cho nó, bạn có thể truyền biểu thức kiểu Số nguyên, không vấn đề gì.
Tuy nhiên, một khi bạn chuyển lên những thứ dạng danh sách (có thể là dạng chung hoặc mảng) điều này không hiệu quả. Họ nên là bất biến - Chỉ có loại chính xác theo yêu cầu và không có loại nào khác có thể thay thế.
Tuy nhiên, một khi bạn bắt đầu sử dụng các loại danh sách (generic hoặc mảng) thì điều này không hoạt động. Chúng phải bất biến - chỉ có loại chính xác được yêu cầu, không có loại nào khác có thể thay thế.
Đó là bởi vì thực ra bạn có thể cả hai viếtVàđọc từ những thứ tầm thường và đó chính là vấn đề. Đây là một ví dụ tầm thường:
Điều này là do bạn thực sự có thể viết và đọc từ danh sách và đó chính là vấn đề. Đây là một ví dụ đơn giản:
Số nguyên i = 5; Số n = i; // điều này là tốt.
Integer[] là = new Integer[10]; Number[] ns = is; // cũng được phải không? Có thể chứ? ns[0] = 5.5; // ... một số đôi Số nguyên firstElement = is[0]; // BÙM!
Dòng cuối cùng cho thấy vấn đề. Bởi vì các kiểu Java cơ bản là đồng biến và sẽ vẫn như vậy, ns[0] = 5,5 dòng phải biên dịch - Tôi đang gán một Double cho một vị trí yêu cầu một Number. Tuy nhiên, điều này dẫn đến một vấn đề ở dòng cuối cùng.
Dòng cuối cùng minh họa vấn đề. Vì các kiểu java cơ sở là hiệp biến và sẽ không thay đổi nên dòng ns[0] = 5.5 phải biên dịch - Tôi gán Double ở bất cứ nơi nào Number được mong đợi. Tuy nhiên, điều này dẫn đến một vấn đề với dòng cuối cùng.
Thuốc generic có thể làm đúng điều này. Câu tương đương chung chung là:
Generics làm điều này rất tốt. Tương đương với thuốc generic như sau:
List là = new ArrayList(); List ns = is; // Điều này không biên dịch được!
Và cung cấp cho bạn các công cụ bạn cần để tạo ra các API tốt; bạn có thể yêu cầu hiệp phương sai (Danh sách mở rộng Số>, nơi mà một Danh sáchlà chấp nhận được, nhưng trình biên dịch ngăn bạn ghi vào danh sách này để đảm bảo rằng vấn đề 'ôi trời, có một số nguyên trong danh sách các số nguyên của tôi' không thể xảy ra), và thậm chí là phản phương sai (Danh sách super Integer>, nơi bạn có thể vượt qua Danh sách, hoặc Danh sách, hoặc một Danh sách<đối tượng="">đối>. Bạn có thể ghi vào đó (bất kỳ số nguyên nào - hoạt động tốt bất kể loại danh sách nào trong 3 loại danh sách đó thực sự được truyền vào), nhưng trình biên dịch ngăn bạn đọc. Hay đúng hơn là trả về Sự vật(vì List nói chung đảm bảo rằng bất cứ thứ gì nó lưu trữ thì ít nhất nó cũng là Object).
và cung cấp cho bạn những công cụ bạn cần để tạo một API tốt; bạn có thể yêu cầu hiệp phương sai (Danh sách mở rộng Số>, trong đó Danh sách
có thể chấp nhận được, nhưng trình biên dịch ngăn bạn ghi vào danh sách này để đảm bảo rằng vấn đề 'rất tiếc, có một số gấp đôi trong danh sách số nguyên của tôi' không xảy ra) hoặc thậm chí trái ngược nhau (Danh sách nơi bạn có thể chuyển Danh sách
, hoặc Danh sách
, hoặc Danh sách
Đây là một mẹo hay: Khi bạn đọc Danh sách mở rộng Số> bạn có thể đang dịch rằng: "Một danh sách, chứa những thứ có kiểu là Số hoặc các kiểu con của Số - bạn biết đấy, những thứ có kiểu là... cái gì đó mở rộng Số". Điều đó là sai. Bạn phải đọc nó như sau: "Một danh sách, giới hạn để chứa một số loại Tôi chỉ đơn giản là không biết ở đây (bạn thấy dấu chấm hỏi không? Nghĩa là 'không biết'). Tất cả những gì tôi biết là: Hạn chế đó là Number hoặc một số kiểu con của nó. Nó có thể là một danh sách chỉ được cho là lưu trữ các số nguyên. Có thể là Doubles. Có thể là bất kỳ Number nào. Không biết. Mọi thứ tôi làm với danh sách này phải hợp lệ bất kể đó có phải là Danh sách hoặc một Danh sách hoặc một Danh sách<đôi>đôi> hoặc bất kỳ cái nào khác Danh sách trong đó X là một kiểu con của Số. Nó phải hoạt động cho TẤT CẢ của chúng hoặc nó không phải là java hợp lệ và trình biên dịch sẽ từ chối nó. Do đó tại sao danh sách.thêm() không hoạt động ở đây - không có giá trị nào vừa là Double vừa là Integer vừa là Number vừa là SomeSubTypeOfNumberYouHaventEvenWrittenYet. Vâng, ngoại trừ giá trị theo nghĩa đen vô giá trị mà thực ra bạn có thể thực sự vượt qua, cách duy nhất để gọi thêm vào không hề.
Đây là một mẹo hay: khi bạn đọc danh sách số mở rộng > bạn có thể dịch sang: "một danh sách chứa những thứ thuộc loại số hoặc kiểu con của số - bạn biết đấy, những thứ thuộc loại .., những thứ mở rộng số". Điều này không đúng. Bạn nên đọc nó như sau: "một danh sách, bị hạn chế chứa một số loại mà tôi hoàn toàn không biết ở đây (xem dấu chấm hỏi? có nghĩa là "không biết"). Tất cả những gì tôi biết là: hạn chế là một con số hoặc một số trong đó Một số kiểu con. Nó có thể là một danh sách chỉ nên lưu trữ số nguyên. Bất cứ điều gì tôi làm với danh sách này đều phải hợp lệ.
,Danh sách
,Danh sách
Hoặc bất kỳ Danh sách nào khác
, trong đó X là một kiểu con của Số. Nó phải hợp lệ cho tất cả Java, nếu không nó không phải là Java hợp lệ và trình biên dịch sẽ từ chối nó. Vì vậy list.add() không hoạt động ở đây - không có giá trị nào vừa là Double vừa là Integer và Numbers và SomeSubTypeOfNumberYouHaventEvenWrittenYet. Được rồi, đây là cách duy nhất để gọi Add, ngoài cách gọi bằng chữ trống mà bạn thực sự có thể chuyển.
Mảng làm điều này hoàn toàn sai.
Mảng là hoàn toàn sai.
Tại sao? Vâng, thuốc generic thực sự phức tạp. Khái niệm rằng bạn cần 4 loại khác nhau mà tất cả đều Danh sách liền kề nhưng hơi khác biệt thì thực sự khá phức tạp:
Tại sao? Chà, thuốc generic thực sự rất phức tạp. Bạn cần 4 loại khác nhau, chúng đều được liệt kê
Liền kề nhưng hơi khác một chút, khái niệm này vốn đã khá phức tạp:
Danh sách (kiểu thô/cũ. Có lẽ nếu java có kiểu chung từ v1.0 thì điều này sẽ không cần thiết).
Danh sách
Danh sách mở rộng Số>
Danh sách siêu Số>
và java đã cố gắng 'giữ mọi thứ đơn giản' nên không thêm điều này. Generics không xuất hiện cho đến java 1.5, hơn một thập kỷ sau đó.
Và Java cố gắng giữ mọi thứ đơn giản nên điều này không được thêm vào. Generics không xuất hiện cho đến Java 1.5, hơn một thập kỷ sau.
Theo một số cách, các nhà thiết kế java dường như (đã lâu lắm rồi, tôi chưa hỏi họ) cũng không biết rằng kiểu thành phần của một thứ listy không thể là covariant. Hoặc, có khả năng hơn, đôi khi bạn muốn viết mã hoạt động trên các mảng tùy ý và các nhà thiết kế ngôn ngữ quyết định để trình biên dịch tránh xa, biến java thành một tình huống ít nhiều được gõ động (tức là trình biên dịch không giúp bạn) trong đó chỉ có thời gian chạy tồn tại để ngăn chặn các vấn đề xảy ra.
Tại một số thời điểm, các nhà thiết kế của Java dường như cũng (đã lâu rồi tôi mới hỏi họ) không nhận ra rằng các loại thành phần của danh sách không thể hiệp biến. Hoặc, nhiều khả năng hơn, đôi khi bạn muốn viết mã hoạt động trên các mảng tùy ý và các nhà thiết kế ngôn ngữ quyết định loại bỏ trình biên dịch, biến Java ít nhiều thành một kiểu động (tức là trình biên dịch không thể giúp bạn) tình huống chỉ có thời gian chạy để ngăn sự cố xảy ra.
Do đó, bạn có thể làm điều này:
Vì vậy, bạn có thể làm điều này:
Đối tượng là = new Integer[10]; Number[] số = (Số[]) là; là[0] = 5,5;
Mã đó biên dịch, nhưng khi bạn chạy nó.. dòng thứ hai hoạt động, nhưng dòng thứ ba thì không - lỗi với ArrayStoreException. Đó là vì mảng biết loại thành phần của chúng là gì và do đó là[0] =.. bài tập kiểm tra: Này, cái gì thế thật sự loại thành phần của đối tượng mảng mà là biến đang trỏ đến? Ồ, nó là Số nguyên[].. hmm, vậy thì ArrayStoreException. Theo nghĩa đó thì đó là một biến thể của ClassCastException.
Mã biên dịch, nhưng khi bạn chạy nó.. dòng thứ hai hoạt động, nhưng dòng thứ ba thì không - nó không thành công, ném ra một ArrayStoreException. Điều này là do các mảng biết các loại thành phần của chúng, do đó, is[0]=.. kiểm tra phép gán: này, loại thành phần thực tế của đối tượng mảng được chỉ ra bởi biến is là gì? Ồ, đó là Integer[].. Vậy thì, ngoại lệ lưu trữ mảng. Theo nghĩa này, nó là một biến thể của ClassCastException.
Tương tự như vậy, bạn thực sự có thể ép kiểu mảng Đối tượng thành bất kỳ kiểu mảng nào bạn muốn, nhưng hệ thống được thiết kế sao cho lưu trữ những thứ vào mảng có thể không thành công với ArrayStoreException, nhưng đọc họ sẽ không bao giờ làm vậy. Bởi vì sẽ dễ dàng hơn để lý luận về mã khi bạn biết một số điều là không thể. Chẳng hạn như các số không phải là số nguyên trong Số nguyên[] mảng.
Tương tự, bạn thực sự có thể chuyển đổi một mảng đối tượng thành bất kỳ kiểu mảng nào bạn muốn, nhưng hệ thống được thiết kế theo cách mà việc lưu trữ dữ liệu vào một mảng có thể bị lỗi với ArrayStoreException, nhưng việc đọc chúng không bao giờ bị lỗi. Bởi vì việc suy luận về mã sẽ dễ dàng hơn khi bạn biết điều gì đó là không thể. Ví dụ: các số không nguyên trong mảng Integer[].
Để đảm bảo quy tắc đó, khi bạn ép kiểu một mảng, thời gian chạy sẽ kiểm tra và sẽ không cho phép bạn nếu điều đó có nghĩa là các hoạt động đọc có thể không thành công. Do đó, tại sao mảng lại mang tính hiệp biến:
Để đảm bảo quy tắc này, khi bạn truyền một mảng, bộ thực thi sẽ kiểm tra và không cho phép bạn thực hiện điều đó nếu điều đó có nghĩa là thao tác đọc có thể không thành công. Do đó, tại sao mảng có tính hiệp biến:
Đối tượng xs = new Integer[100]; Number[] ns = (Number[]) xs; // được phép xs = số mới[100]; Integer[] là = (Integer[]) xs; // không được phép
Trong đó 'không được phép' có nghĩa là: Thường biên dịch tốt, nhưng khi chạy sẽ dẫn đến Ngoại lệ ClassCast.
Trường hợp 'không được phép' có nghĩa là: thường biên dịch tốt nhưng gây ra ngoại lệ ClassCastException khi chạy.
Lý do duy nhất khiến nó hoạt động theo cách đó là dòng 'được phép' vẫn bị hỏng (ở đây bạn mong đợi một mảng có kiểu Con số[] để cho phép bạn ghi bất kỳ Số nào vào đó, trong khi ở đây thì không và sẽ không thành công với ArrayStoreEx trừ khi đó là Số nguyên), nhưng được phép vì nó không thể bị hỏng khi đọc từ nó (bất cứ thứ gì trong mảng đó, ít nhất nó là một Số. Bởi vì tất cả các Số nguyên đều là Số và thứ duy nhất mà mảng đó có thể lưu trữ là các đối tượng Số nguyên). Trong khi thứ hai không được phép, bởi vì nếu nó được phép, đọc từ nó có thể gây ra vấn đề. Ngoại lệ ArrayStoreException tồn tại; Ngoại lệ ArrayReadException không.
Lý do duy nhất khiến nó hoạt động theo cách này là vì dòng 'Được phép' vẫn bị hỏng (vì bạn mong đợi một mảng kiểu Numbers[] cho phép bạn viết bất kỳ số nào vào nó, trong khi ở đây, trừ khi đó là Số nguyên, nếu không thì Mảng kiểu này loại sẽ không và sẽ thất bại khi sử dụng ArrayStoreEx), nhưng được phép vì nó không thể bị ngắt kết nối trong khi đọc nó (dù là gì trong mảng thì ít nhất nó cũng là một số). Bởi vì tất cả các số nguyên đều là số và thứ duy nhất mà một mảng có thể lưu trữ là một đối tượng Số nguyên). Và cái thứ hai không được phép vì việc đọc từ nó có thể gây ra vấn đề nếu nó được cho phép. ArrayStoreException tồn tại; ArrayReadException không tồn tại.
Tại sao sự lựa chọn lại được thực hiện theo cách này? Đến một lúc nào đó, chúng ta đã đi đến ngõ cụt. Câu trả lời cho cái đó là: "Bởi vì thông số kỹ thuật nói như vậy" và nếu bạn muốn biết tại sao cái đó trong trường hợp này, câu trả lời là: "Bởi vì các nhà thiết kế lúc đó muốn như vậy". Bất kỳ câu hỏi 'nhưng.. tại sao?' nào nữa nên được chuyển trực tiếp đến James Gosling và cộng sự.
Tại sao bạn lại đưa ra lựa chọn này? Theo một cách nào đó, chúng ta đã đi vào ngõ cụt. Câu trả lời cho câu hỏi này là: "Bởi vì các thông số kỹ thuật nói như vậy", và nếu bạn đang thắc mắc tại sao lại như vậy thì câu trả lời là: "Bởi vì các nhà thiết kế vào thời điểm đó muốn nó như vậy". Còn điều gì muốn hỏi nữa không, nhưng... tại sao? Các câu hỏi nên được chuyển tới James Gosling và các đồng nghiệp của anh ấy.
Thêm câu trả lời
Qua 1/5 câu trả lời này, tôi đã có thể biết tác giả là ai. Contravariance/Covariance/Invariance là những chủ đề chính không dễ hiểu. Trình bày rất hay, và thay mặt tất cả chúng tôi, cảm ơn vì đã giáo dục chúng tôi rất nhiều. 1+
Với câu trả lời này tôi đã biết tác giả là ai. Phương sai nghịch đảo/hiệp phương sai/bất biến là những chủ đề chính không dễ hiểu. Nói hay lắm, từ tất cả chúng tôi, cảm ơn bạn đã giáo dục chúng tôi tốt. 1+
Tôi không chắc điều này có trả lời được câu hỏi của OP không. Tại sao dòng đó lại biên dịch? Trình biên dịch sẽ đánh giá số nguyên i = 1,0 + 2,0; tại thời điểm biên dịch và đưa ra lỗi. Nhưng tôi khá chắc chắn cả hai diễn viên (Số nguyên[]) và mới từ khóa không bao giờ được trình biên dịch đánh giá như một nghĩa đen. (Nhưng tôi đã không kiểm tra lại điều đó.) Vì vậy, không có lựa chọn nào: cả hai mới và dàn diễn viên chỉ được đánh giá khi chạy.
Tôi không chắc điều đó trả lời được câu hỏi của người đại diện. Tại sao dòng mã này nên được biên dịch? Trình biên dịch sẽ đánh giá int i=1.0+2.0 tại thời điểm biên dịch và đưa ra lỗi. Nhưng tôi khá chắc chắn rằng cả CAST(Integer[]) lẫn từ khóa mới sẽ không được trình biên dịch đánh giá như văn bản. (Nhưng tôi đã không kiểm tra lại điều này.) Vì vậy không có lựa chọn nào khác: cả new và cast chỉ đánh giá khi chạy.
Tôi đoán nói cách khác, tôi đang hiểu câu hỏi của OP là hỏi "Kiểu Object[] nằm ngay đó, kiểu ép kiểu (Integer[]) cũng nằm ngay đó, tại sao trình biên dịch không thể đánh giá và phát hiện lỗi ngay lập tức?" (Chỉnh sửa: nhưng số nguyên i = (int)(1.0+2.0); được đánh giá tại thời điểm biên dịch, vì vậy tôi đoán tham chiếu ép kiểu chỉ xảy ra tại thời điểm chạy, các hàm nguyên thủy có thể được đánh giá tại thời điểm biên dịch; có thể đây cũng là một nguồn gây nhầm lẫn.)
Tôi đoán nói cách khác, tôi hiểu câu hỏi của OP là hỏi "Loại object[] ở đó, chuyển đổi kiểu (Integer[]) ở đó, tại sao trình biên dịch không thể đánh giá nó ngay lập tức và tìm ra lỗi?" : Nhưng int i=(Int)(1.0+2.0); được đánh giá tại thời gian biên dịch, vì vậy tôi đoán việc truyền tham chiếu chỉ xảy ra trong thời gian chạy và các nguyên hàm có thể được đánh giá tại thời gian biên dịch; đây cũng có thể là một nguồn khó hiểu.)
Vấn đề sẽ là với ns[0] = 5.5; // ... một số đôi, không phải với Số nguyên firstElement = is[0]; // BÙM!.
Vấn đề sẽ là ns[0]=5.5; //...a Double, không có Integer FirstElement=is[0];
@markspace Dòng cuối cùng của câu trả lời giải thích điều đó: Đó là lời giải thích một từ: "Bởi vì". Spec nói như vậy. Làm đúng thì rất phức tạp (xem phần giữa câu trả lời: Co/Contra/Invariance), có lẽ thiết kế java v1.0 đã bỏ cuộc để cố gắng hiểu nó tại thời điểm biên dịch.
Dòng cuối cùng trong câu trả lời của @ markspace giải thích điều này: đó là lời giải thích chỉ bằng một từ: bởi vì. Spike đã nói như vậy. Làm điều đó một cách chính xác là rất phức tạp (xem phần giữa của câu trả lời: CO/Contra/Invarance), có lẽ là do thiết kế Java v1.0 đã bị bỏ qua để hiểu nó tại thời điểm biên dịch.
Tôi biết chúng là loại ẩn danh, nhưng tôi không hiểu cú pháp của Razor. Trong một số tài liệu tôi tìm thấy ví dụ này: @Html.Label("Xin chào", new { htmlAtributes = new { id = "h
Về: new Object(new Array()) Tôi có một câu hỏi khá cơ bản mà tôi thực sự không thể tự đưa ra câu trả lời và tôi đang tìm kiếm lời khuyên: Khi khởi tạo một đối tượng trong js, hãy sử dụng cái gì đó như thế này: var obj = new Object ();
Sự khác biệt giữa "Thư mục mới", "Thư mục nguồn mới" và "Gói mới" khi nhấp chuột phải vào dự án trong Eclipse là gì? Tất cả họ dường như đều đang làm điều tương tự và các trích dẫn không nói lên nhiều điều. Cảm ơn Câu trả lời hay nhất Thư mục mới Tạo một thư mục mới trong dự án. Tạo văn bản nguồn mới
Tôi đã thử nghiệm Bolt-cm được vài ngày và tôi đang cố gắng hiểu cách thức hoạt động của nó. Tôi muốn biết sự khác biệt giữa trang mới, mục mới và chương trình giới thiệu mới. Tôi đã đọc cái này và nó không lấp đầy những khoảng trống. Trang, bài viết và Sh có câu trả lời hay nhất
Cập nhật: Cảm ơn tất cả các câu trả lời. Giải pháp rõ ràng nhất mà tôi tìm thấy là: if ( k(Arrays.asList(new LinkedList<>())); Tôi có một phương pháp đệ quy tạo ra tất cả các kết hợp "k out of n" từ một danh sách.
Bây giờ tôi muốn biết các hướng dẫn này phân bổ bộ nhớ như thế nào. Ví dụ: điều gì sẽ xảy ra nếu tôi nhận được mã: x = new int[5]; y = new int[5]; Nếu những mã này được phân bổ thì nó thực sự nằm trong RAM như thế nào? là giữ lại số nguyên cho mỗi biến
Tôi muốn nó được ghi vào out.txt mà không xóa nó - chỉ cần thêm vào cuối. Tuy nhiên, khi tôi sử dụng hai phương pháp sau: public void addEmails(ArrayList email){ for (i
Tôi đang phân bổ bộ nhớ mà sau này sẽ được sử dụng để xây dựng một đối tượng được đặt mới. Tôi nên sử dụng toán tử mới (n) hay tôi nên sử dụng char [n] mới không dấu? Tại sao? Yếu tố câu trả lời hay nhất: new[] là bắt buộc
Xin lỗi nếu câu hỏi này đã được hỏi trước đây, nhưng tôi muốn đưa ra câu trả lời ngắn gọn về sự khác biệt giữa hai cách sử dụng sau đây. VS dường như chấp nhận tất cả chúng dưới dạng mã hợp lệ. khoảng trống tĩnh riêng tư doSomeWork() { /
Vui lòng cho tôi biết đoạn mã này đang làm gì, nó có tạo ra mảng đa chiều không (tôi nghĩ là không)? Đoạn mã.. var hanoi_peg = new Array( new Array( 5, 4, 3, 2, 1,
Nhiều người nói rằng bạn nên tránh sử dụng new Object, new Array() và thay vào đó hãy sử dụng {}. [] và đúng/sai. Lợi ích của việc sử dụng cấu trúc theo nghĩa đen để có được một phiên bản mới của một đối tượng hoặc mảng thay vì sử dụng cấu trúc mới là gì? Tôi biết Crockfor
Tôi đang phát triển một thư viện nguồn mở bị rò rỉ bộ nhớ. Thư viện này là một dịch vụ truyền dữ liệu được xây dựng xung quanh boost::asio. Phía máy chủ sử dụng hệ thống quản lý bộ nhớ heap cung cấp bộ nhớ để chứa một số lượng mẫu giới hạn trong khi chúng chờ được đẩy qua kết nối tcp
Khi nghĩ về một cái gì đó như auto x = new T; tiêu chuẩn có yêu cầu bộ nhớ phải đến từ toán tử mới - lớp cụ thể hay toàn cục không? Nghĩa là, nếu toán tử new của lớp cụ thể bị thiếu, không có cách nào để loại bỏ tất cả khỏi
Vì tò mò: tại sao C++ chọn a = new A thay vì a = A.new làm cách khởi tạo một đối tượng? Không phải cái sau hướng đối tượng hơn sao? Câu trả lời hay nhấtChỉ vì tò mò: Tại sao
Câu hỏi này đã có câu trả lời ở đây: Sự khác biệt giữa 'toán tử mới' và 'toán tử mới'? (8 câu trả lời) Đã đóng 8 năm trước. Câu hỏi phỏng vấn: nhà điều hành "mới" và
Tôi đang thiết kế giao diện cho một ứng dụng hiển thị một số dữ liệu được lấy từ cơ sở dữ liệu trong TableLayout. Giờ đây, Chế độ xem mặc định có dạng dọc và bao gồm menu thả xuống và bảng ba cột. Khi người dùng chuyển sang chế độ ngang, vòng xoay và các tùy chọn của nó có thể
Tôi là một lập trình viên xuất sắc, rất giỏi!