Java没有指针,只有引用,如何关联变量,实现各类数据结构?

createh52个月前 (02-01)技术教程9

C语言离不开指针,指针作为一种派生类型,是数据关联的一种主要手段(实现顺序存储和链式存储)。数组下标运算也只是指针算术运算的语法糖。其中数组名是一个常量(为安全考量),数组下标运算替换为指针运算,由C编译器完成。

C++语言针对指针的复杂性和安全性问题,引入了引用类型,引用类型是一种特殊的指针,是一种常量类型,在不同的上下文中可以显式使用引用的地址属性或值属性。

C++也不能没有指针类型(没法实现链式存储),除非引用类型是一种非常量,但这又违背了引入引用的初衷,C++是通过原生指针、引用、智能指针、原生数组、vector等语法机制来实现相互补充的。

Java舍弃了指针类型,其引用类型也可以是一个变量(可使用操赋值运算符,但不支持算术运算),因为Java用GC机制,C++的动态内存泄漏问题在Java这里不是问题。数组也是一种引用类型。对于Java类型来说,分为两大类型,一种是基本类型,一种是引用类型。非基本类型(复合类型)全部统一建立在堆上,这块堆内存的首地址保存栈上。当然,引用的底层也是指针,但这只是编译器层面的问题。

Java作为试图改良C++的编程语言,一定程度上摒弃了C++的复杂性,其中就包括指针,虽然也有引用类型,但是一个与C++不同的引用类型,Java的引用也是一个特殊的指针(指针是显式的地址使用),但不是一个常量,可以用做左值,没有C++考虑让引用作为常量的原因(安全问题)的问题吗,没有,因为其有自动GC(Garbage collection 垃圾回收)功能,且所有对象都是通过一个引用变量来操作,对象本身生存在堆内存上,引用本身生存在栈内存上,由GC根据对象引用的情况来确定对象回收的时间。

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

引用传参时,在函数体内是隐式取值还是取址形成副作用,取决于上下文。

我们知道,对于数据结构而言,非线性结构其实质是一个二维的线性结构。例如,图这种数据结构的存储结构可以是邻接矩阵或邻接表。线性表的存储结构主要是使用顺序存储和链式存储。

我们知道,在C++中,数组下标操作符[]是对应指针运算符的语法糖,对于Java来说,没了指针,也没有指针的加减运算,只是限制到了下标操作符[]而已。

Java的数组是动态数组,存储在堆上。数组名本身是一个栈变量,存储建立数组的堆内存的地址。另外,Java的数组提供了length属性。

指针及其算术运算在循环操作中有一定优势,而Java通过一定的语法机制来实现相同效果。

一些容器提供了size()和isEmpty()方法,在循环方法,也提供了以下一些语法机制的支持:

利用for范围迭代(底层也是迭代器实现)

迭代器iterator.hasNext()

for each循环

对于链式存储,不需要指针的加减运算,对于C++和Java(其引用支持赋值运算)而,其实现是一致的,对于结点类而言,都是使用了一个地址域(指针或引用)来联结:

import java.util.Scanner;
import java.util.Random;
class Node{
    private Node next;
    private int  value;
    public Node ( int val ){
        value = val;
        next = null;
    }
    public int  getValue() { return value; }
    public Node getNext()  { return next; }
    public void setValue( int val ) { value = val; }
    public void setNext( Node nxt ) { next = nxt; }
    public String toString() { return value + ", "; }}class LinkedList{
    private Node headPtr = null;
    // The constructor creates an empty list
    public LinkedList()  {
        headPtr = null;
    }
    // Determine if the List is empty
    public boolean isEmpty(){
        return headPtr == null;
        // future work
    }
    // Insert one Node containing data at the head
    // of the list.  This will be explained in a few pages.
    public void insertFirst( int data ){
        Node newFirst = new Node( data );
        newFirst.setNext( headPtr );
        headPtr = newFirst;
    }
    public void deleteFirst(){
        if( headPtr != null )
        {
            headPtr = headPtr.getNext();  // headPtr now points at second node, or
            // is null if there was no second node.
        }
    }
    // Traverse the list, printing each node
    public void traverse() {
        Node p = headPtr;
        while( p != null )
        {
            System.out.print( p );
            p = p.getNext();
        }
    }
}
public class Main{
    public static void main( String[] args )
    {
        LinkedList list = new LinkedList();
        Scanner scan = new Scanner( System.in );
        Random rand = new Random();
        System.out.print("How many nodes? ");
        int numNodes = scan.nextInt();
        for( int j = 0; j

-End-

相关文章

Java数组数据的操作之检查日期格式是否正确

程序源代码/***Title:数组数据的操作*@author author*version 0.1*/public class myArray034{//初始化数组变量char[] cNum = {'...

protobuf之序列化数据和反序列化数据基础知识

什么是 protobufProtocal Buffers(简称protobuf)是谷歌的一项技术,用于结构化的数据序列化、反序列化。Protocol Buffers 是一种语言无关、平台无关、可扩展的...

2022年Android面试题及答案收集(不断更新中)

前言找工作、招人必备之良品。后期不断完善中……如何招聘人,搜集了一些知识点。如何做好应聘准备,也收集了一些主要知识点,供你参考。Android基础知识:基本涵盖Android所有知识体系,四大组件,F...

java之反射(3)方法method(java反射的几种方法)

#头条创作挑战赛#一、获取字节码文件有一个User类,里面有一个login函数和eat函数。public class User { public boolean login(String cn...

Java中的字符串(String)最大长度限制

看String的源码可以看出来,String实际存储数据的是char value[],数组的长度是int类型,整数在java中是有限制的,我们通过源码来看看int类型对应的包装类Integer可以看到...

C 语言简单编程速成(c语言编程快速入门)

我们将所有的 C 语言要素放置到一份易读的备忘录上。? 来源:linux.cn ? 作者:Seth Kenlon ? 译者:郑 ?(本文字数:5500,阅读时长大约:8 分钟)我们将所有的 C 语言要...