Tôi biết Java không có con trỏ, nhưng tôi nghe nói rằng các chương trình Java có thể được tạo bằng con trỏ và điều này có thể được thực hiện bởi một số ít chuyên gia về java. Có đúng không?
Tôi biết Java không có con trỏ, nhưng tôi nghe nói rằng các chương trình Java có thể được tạo bằng con trỏ và điều này có thể được thực hiện bởi một số ít chuyên gia về java. Có đúng không?
Câu trả lời:
Tất cả các đối tượng trong Java đều là tham chiếu và bạn có thể sử dụng chúng như con trỏ.
abstract class Animal
{...
}
class Lion extends Animal
{...
}
class Tiger extends Animal
{
public Tiger() {...}
public void growl(){...}
}
Tiger first = null;
Tiger second = new Tiger();
Tiger third;
Tham chiếu giá trị rỗng:
first.growl(); // ERROR, first is null.
third.growl(); // ERROR, third has not been initialized.
Vấn đề về răng cưa:
third = new Tiger();
first = third;
Mất tế bào:
second = third; // Possible ERROR. The old value of second is lost.
Bạn có thể làm cho điều này an toàn bằng cách trước tiên đảm bảo rằng không cần thêm giá trị cũ của thứ hai hoặc chỉ định một con trỏ khác giá trị của thứ hai.
first = second;
second = third; //OK
Lưu ý rằng việc cung cấp giá trị thứ hai theo những cách khác (NULL, mới ...) cũng là một lỗi tiềm ẩn và có thể dẫn đến mất đối tượng mà nó trỏ tới.
Hệ thống Java sẽ ném một ngoại lệ ( OutOfMemoryError
) khi bạn gọi mới và bộ cấp phát không thể cấp phát ô được yêu cầu. Điều này rất hiếm và thường là kết quả của đệ quy bỏ chạy.
Lưu ý rằng, từ quan điểm ngôn ngữ, việc bỏ các đối tượng vào trình thu gom rác không phải là lỗi. Nó chỉ là một cái gì đó mà các lập trình viên cần phải lưu ý. Cùng một biến có thể trỏ đến các đối tượng khác nhau tại các thời điểm khác nhau và các giá trị cũ sẽ được lấy lại khi không có con trỏ nào tham chiếu đến chúng. Nhưng nếu logic của chương trình yêu cầu duy trì ít nhất một tham chiếu đến đối tượng, Nó sẽ gây ra lỗi.
Những người mới làm quen thường mắc lỗi sau.
Tiger tony = new Tiger();
tony = third; // Error, the new object allocated above is reclaimed.
Điều bạn có thể muốn nói là:
Tiger tony = null;
tony = third; // OK.
Đúc không đúng:
Lion leo = new Lion();
Tiger tony = (Tiger)leo; // Always illegal and caught by compiler.
Animal whatever = new Lion(); // Legal.
Tiger tony = (Tiger)whatever; // Illegal, just as in previous example.
Lion leo = (Lion)whatever; // Legal, object whatever really is a Lion.
Con trỏ trong C:
void main() {
int* x; // Allocate the pointers x and y
int* y; // (but not the pointees)
x = malloc(sizeof(int)); // Allocate an int pointee,
// and set x to point to it
*x = 42; // Dereference x to store 42 in its pointee
*y = 13; // CRASH -- y does not have a pointee yet
y = x; // Pointer assignment sets y to point to x's pointee
*y = 13; // Dereference y to store 13 in its (shared) pointee
}
Con trỏ trong Java:
class IntObj {
public int value;
}
public class Binky() {
public static void main(String[] args) {
IntObj x; // Allocate the pointers x and y
IntObj y; // (but not the IntObj pointees)
x = new IntObj(); // Allocate an IntObj pointee
// and set x to point to it
x.value = 42; // Dereference x to store 42 in its pointee
y.value = 13; // CRASH -- y does not have a pointee yet
y = x; // Pointer assignment sets y to point to x's pointee
y.value = 13; // Deference y to store 13 in its (shared) pointee
}
}
CẬP NHẬT: như được đề xuất trong các ý kiến, người ta phải lưu ý rằng C có số học con trỏ. Tuy nhiên, chúng tôi không có điều đó trong Java.
Java không có con trỏ. Bất cứ khi nào bạn tạo một đối tượng trong Java, bạn thực sự đang tạo một con trỏ tới đối tượng; con trỏ này sau đó có thể được đặt thành một đối tượng khác hoặc thành null
, và đối tượng ban đầu sẽ vẫn tồn tại (đang chờ thu gom rác).
Những gì bạn không thể làm trong Java là số học con trỏ. Bạn không thể bỏ qua một địa chỉ bộ nhớ cụ thể hoặc gia tăng một con trỏ.
Nếu bạn thực sự muốn có được mức thấp, cách duy nhất để làm điều đó là với Giao diện Bản địa Java ; và thậm chí sau đó, phần cấp thấp phải được thực hiện bằng C hoặc C ++.
Vì Java không có kiểu dữ liệu con trỏ nên không thể sử dụng con trỏ trong Java. Ngay cả một số chuyên gia sẽ không thể sử dụng con trỏ trong java.
Xem thêm điểm cuối cùng trong: Môi trường ngôn ngữ Java
Có những con trỏ trong Java, nhưng bạn không thể thao tác chúng theo cách mà bạn có thể làm trong C ++ hoặc C. Khi bạn truyền một đối tượng, bạn đang truyền một con trỏ đến đối tượng đó, nhưng không theo nghĩa giống như trong C ++. Đối tượng đó không thể được tham chiếu. Nếu bạn đặt các giá trị của nó bằng cách sử dụng các bộ truy cập gốc của nó, nó sẽ thay đổi vì Java biết vị trí bộ nhớ của nó thông qua con trỏ. Nhưng con trỏ là bất biến. Khi bạn cố gắng đặt con trỏ đến một vị trí mới, thay vào đó bạn sẽ nhận được một đối tượng cục bộ mới có cùng tên với đối tượng kia. Vật ban đầu không đổi. Đây là một chương trình ngắn gọn để chứng minh sự khác biệt.
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone {
public static void main(String[] args) throws java.lang.Exception {
System.out.println("Expected # = 0 1 2 2 1");
Cat c = new Cat();
c.setClaws(0);
System.out.println("Initial value is " + c.getClaws());
// prints 0 obviously
clawsAreOne(c);
System.out.println("Accessor changes value to " + c.getClaws());
// prints 1 because the value 'referenced' by the 'pointer' is changed using an accessor.
makeNewCat(c);
System.out.println("Final value is " + c.getClaws());
// prints 1 because the pointer is not changed to 'kitten'; that would be a reference pass.
}
public static void clawsAreOne(Cat kitty) {
kitty.setClaws(1);
}
public static void makeNewCat(Cat kitty) {
Cat kitten = new Cat();
kitten.setClaws(2);
kitty = kitten;
System.out.println("Value in makeNewCat scope of kitten " + kitten.getClaws());
//Prints 2. the value pointed to by 'kitten' is 2
System.out.println("Value in makeNewcat scope of kitty " + kitty.getClaws());
//Prints 2. The local copy is being used within the scope of this method.
}
}
class Cat {
private int claws;
public void setClaws(int i) {
claws = i;
}
public int getClaws() {
return claws;
}
}
Điều này có thể được chạy tại Ideone.com.
Java không có các con trỏ như C có, nhưng nó cho phép bạn tạo các đối tượng mới trên heap được các biến "tham chiếu". Việc thiếu con trỏ là ngăn các chương trình Java tham chiếu đến các vị trí bộ nhớ một cách bất hợp pháp, đồng thời cũng cho phép Máy ảo Java tự động thực hiện Thu dọn rác.
Bạn có thể sử dụng địa chỉ và con trỏ bằng cách sử dụng lớp Không an toàn. Tuy nhiên, như tên cho thấy, những phương pháp này KHÔNG AN TOÀN và nói chung là một ý tưởng tồi. Việc sử dụng không đúng cách có thể dẫn đến việc JVM của bạn chết ngẫu nhiên (thực tế là cùng một vấn đề là sử dụng con trỏ không chính xác trong C / C ++)
Mặc dù bạn có thể đã quen với các con trỏ và nghĩ rằng bạn cần chúng (vì bạn không biết cách viết mã theo bất kỳ cách nào khác), bạn sẽ thấy rằng bạn không làm như vậy và bạn sẽ tốt hơn cho nó.
Về mặt kỹ thuật, tất cả các đối tượng Java đều là con trỏ. Tất cả các kiểu nguyên thủy đều là giá trị. Không có cách nào để kiểm soát thủ công các con trỏ đó. Java chỉ sử dụng tham chiếu nội bộ.
Không thực sự, không.
Java không có con trỏ. Nếu bạn thực sự muốn, bạn có thể thử mô phỏng chúng bằng cách xây dựng xung quanh một cái gì đó giống như phản chiếu, nhưng nó sẽ có tất cả sự phức tạp của con trỏ mà không có lợi ích nào .
Java không có con trỏ vì nó không cần chúng. Bạn hy vọng loại câu trả lời nào từ câu hỏi này, tức là trong sâu thẳm bạn hy vọng mình có thể sử dụng chúng cho việc gì đó hay đây chỉ là sự tò mò?
Tất cả các đối tượng trong java được chuyển tới các hàm bằng bản sao tham chiếu ngoại trừ các đối tượng nguyên thủy.
Trên thực tế, điều này có nghĩa là bạn đang gửi một bản sao của con trỏ tới đối tượng gốc chứ không phải là bản sao của chính đối tượng.
Vui lòng để lại bình luận nếu bạn muốn một ví dụ để hiểu điều này.
swap
hàm trong Java sẽ hoán đổi hai đối tượng.
Như những người khác đã nói, câu trả lời ngắn gọn là "Không".
Chắc chắn, bạn có thể viết mã JNI chơi với con trỏ Java. Tùy thuộc vào những gì bạn đang cố gắng hoàn thành, có thể điều đó sẽ đưa bạn đến đâu đó và có thể không.
Bạn luôn có thể mô phỏng các điểm bằng cách tạo một mảng và làm việc với các chỉ mục trong mảng. Một lần nữa, tùy thuộc vào những gì bạn đang cố gắng hoàn thành, điều đó có thể hữu ích hoặc không.
từ cuốn sách có tên Giải mã Android của Godfrey Nolan
Bảo mật quy định rằng con trỏ không được sử dụng trong Java nên tin tặc không thể thoát ra khỏi ứng dụng và xâm nhập vào hệ điều hành. Không có con trỏ nào có nghĩa là thứ gì đó khác ---- trong trường hợp này, JVM ---- phải đảm nhận việc cấp phát và giải phóng bộ nhớ. Rò rỉ bộ nhớ cũng nên trở thành dĩ vãng, hoặc lý thuyết là vậy. Một số ứng dụng được viết bằng C và C ++ nổi tiếng với việc làm rò rỉ bộ nhớ như một cái rây bởi vì các lập trình viên không chú ý đến việc giải phóng bộ nhớ không mong muốn vào thời điểm thích hợp ---- không phải bất kỳ ai đọc nó sẽ phạm tội như vậy. Việc thu gom rác cũng sẽ làm cho các lập trình viên làm việc năng suất hơn, với ít thời gian hơn để gỡ lỗi các vấn đề về bộ nhớ.
bạn cũng có thể có con trỏ cho các chữ. Bạn phải tự mình thực hiện chúng. Nó là khá cơ bản cho các chuyên gia;). Sử dụng một mảng int / object / long / byte và bạn đã có những kiến thức cơ bản để triển khai con trỏ. Bây giờ bất kỳ giá trị int nào cũng có thể là một con trỏ tới mảng int [] đó. Bạn có thể tăng con trỏ, bạn có thể giảm con trỏ, bạn có thể nhân con trỏ. Bạn thực sự có số học con trỏ! Đó là cách duy nhất để triển khai 1000 lớp thuộc tính int và có một phương thức chung áp dụng cho tất cả các thuộc tính. Bạn cũng có thể sử dụng một mảng [] byte thay vì một int []
Tuy nhiên, tôi ước gì Java sẽ cho phép bạn chuyển các giá trị theo nghĩa đen bằng cách tham chiếu. Một cái gì đó dọc theo dòng
//(* telling you it is a pointer)
public void myMethod(int* intValue);
Tất cả các đối tượng java đều là con trỏ vì một biến chứa địa chỉ được gọi là con trỏ và đối tượng giữ địa chỉ. Vì vậy đối tượng là biến con trỏ.