java 内存指针_Java里的指针

本文探讨了Java中的引用与C/C++中的指针之间的相似性和差异性,详细解析了这两种语言中对象的处理方式,以及它们在内存管理上的不同之处。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天又被人问道,java里面是否有指针的问题。如果一定要在是或否里选择一个,那么答案是否定的,java中没有指针。但是,java中的引用(reference)和c/c++中的指针(pointer)又有什么关系呢?

一、指针

在计算机科学中,指针是编程语言中的一个对象,利用地址,它的值直接指向存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址的内存单元。

C++标准中规定,“指针”概念不适用于成员指针(不包含指向静态成员的指针)。C++标准规定,参见维基百科,指针分为两类:

object pointer type:指向void或对象类型,表示对象在内存中的字节地址或空指针

function pointer type:指代一个函数

二、C/C++中的指针与引用

1、指针和引用的相同点和不同点

★相同点:

●都是地址的概念;

指针指向一块内存,它的内容是所指内存的地址;而引用则是某块内存的别名。

★不同点:

●指针是一个实体,而引用仅是个别名;

●引用只能在定义时被初始化一次,之后不可变;指针可变;引用“从一而终”,指针可以“见异思迁”;

●引用没有const,指针有const,const的指针不可变;(具体指没有int& const a这种形式,而const int& a是有 的, 前者指引用本身即别名不可以改变,这是当然的,所以不需要这种形式,后者指引用所指的值不可以改变)

●引用不能为空,指针可以为空;

●“sizeof 引用”得到的是所指向的变量(对象)的大小,而“sizeof 指针”得到的是指针本身的大小;

●指针和引用的自增(++)运算意义不一样;

●引用是类型安全的,而指针不是(引用比指针多了类型检查)

2、 C++类的对象和类的指针的区别

如下程序:

#include

#include

using namespace std;

class Student

{

public:

static int number;

string name;

void set(string str)

{

name = str;

number++; // 调用静态数据成员

}

void print() // 态成员函数 print()

{

std::cout < < name <

}

};

int Student::number = 0; // 静态数据成员初始化

int main(int argc, char** argv)

{

Student* s1;

s1 = new Student();

s1->set("111");

Student s2;

s2.set("222");

s1->print();

s2.print();

return 0;

}

对于类student ,定义了一个对象 和一个指针。

类的指针:是一个内存地址值,他指向内存中存放的类对象(包括一些成员变量所赋的值).

类的对象,是利用类的构造函数在内存中分配一块内存(包括一些成员变量所赋的值).

定义对象实例时,分配了内存。指针变量则未分配类对象所需内存

指针变量是间接访问,但可实现多态(通过父类指针可调用子类对象),并且没有调用构造函数。

至于那个效率高要看程序调用过程而定。

三、Java中的引用

在Java中的引用类型,是指除了基本的变量类型之外的所有类型,所有的类型在内存中都会分配一定的存储空间(形参在使用的时候也会分配存储空间,方法调用完成之后,这块存储空间自动消失), 基本的变量类型只有一块存储空间(分配在stack中), 而引用类型有两块存储空间(一块在stack中,一块在heap中), 方法形参的值传递(引用)是指形参和传进来的参数指向同一个值的内存(heap)中。

实际上java语言并不是没有指针,而是对指针进行了伪装:使用上泛化、强化和简单化,概念上淡化和弱化。

C++中可以有对象类型的变量和对象指针类型,两者的区别如下: Object oo = Object(); Object * oop = new Object(); 也就是说当使用new方式时,是动态为对象分配内在并将地址赋给oop这个指针变量。

JAVA中只有一种相关类型:对象类型,可是它的表现形式却是这样的: Object oo = new Object(); 比较一下,原来它就是使用了C++的动态内在分配方式创建了一个对象,并把地址返回给了oo变量,也就是说oo本质上就是一个指针变量。

引申一下:JAVA中的对象类型本质上应该叫做 对象指针 类型。那么传统的对象类型呢?在JAVA里已经不见了踪影!既然没有了传统的对象类型,那么 对象指针变量 前面的*也就可以不要了。对象指针变量也就可以简称为对象变量了,反正也不会和其它概念混淆! 所有的对象变量都是指针,没有非指针的对象变量,想不用指针都不行,这就是指针的泛化和强化。 不叫指针了,就叫对象变量,这就是概念上的淡化和弱化。 没有了指针的加减运算,也没有了*、->等运算符,这是对指针的简单化。

1.JAVA强调所有的对象赋值和传递都是引用,解释如下:

Object a=new Object(); 并不是将新生成的对象赋给a,a是对新生成对象的引用。

Object a=new Object(); Object b; b=a; b并不是一个新对象,它是对a对象的引用。

其实,a是指针,b也是指针,将a的值赋给b,也就是将a所存储的地址赋给b,b自然指向了a所指向的对象。

2.而两个对象的相等比较不是比较两个对象的值是否相同,是比较两个对象是不是相同的引用。解释如下:

Object a=new Object(); Object b=a; a==b为真,两个对象引用相同。

String a=new String(“abc”); String b=new String(“abc”); a==b为假,两个对象引用不同。

其实,==的意义并没有变。a是指针,b也是指针,a、b存储的都是地址,当两个变量存储了同一个对象的地址时,这两个地址当然相等,a==b自然是真。当两个变量存储了不同对象的地址,这两个地址值当然不同,a==b自然为假。

最后的一个例子用java里面用引用实现指针的功能:

public class Foo1 {

public static void main(String[] args) {

FakeInt a = new FakeInt(10);

FakeInt b = new FakeInt(20);

Foo1.exchange(a, b);

System.out.println("结果为:\n"+a.getValue());

System.out.println(b.getValue());

}

public static void exchange(FakeInt a, FakeInt b) {

FakeInt t = new FakeInt(a.getValue());

a.setValue(b.getValue());

b.setValue(t.getValue());

}

}

class FakeInt {

private int value;

public FakeInt(int i) {

this.value = i;

}

public void setValue(int i) {

this.value = i;

}

public int getValue() {

int v = this.value;

return v;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值