精华内容
下载资源
问答
  • 2021-03-01 10:23:54

    Java中的所有对象都是引用,您可以像指针一样使用它们。

    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;

    引用null:

    first.growl(); // ERROR, first is null.

    third.growl(); // ERROR, third has not been initialized.

    混淆问题:

    third = new Tiger();

    first = third;

    失去细胞:

    second = third; // Possible ERROR. The old value of second is lost.

    你可以通过首先确保没有进一步需要旧值的第二或分配另一个指针的值第二。

    first = second;

    second = third; //OK

    注意,以其他方式给出第二个值(NULL,new …)也是一个潜在的错误,可能导致丢失它指向的对象。

    当您调用new并且分配器无法分配所请求的单元时,Java系统将抛出异常(OutOfMemoryError)。这是非常罕见的,通常是由于run-away递归。

    注意,从语言的角度来看,将对象放弃到垃圾收集器根本不是错误。它只是程序员需要知道的东西。同一个变量可以指向不同时间的不同对象,并且当没有指针引用它们时,旧值将被回收。但是如果程序的逻辑需要维护至少一个对象的引用,则会导致错误。

    新手经常出现以下错误。

    Tiger tony = new Tiger();

    tony = third; // Error, the new object allocated above is reclaimed.

    你可能想说的是:

    Tiger tony = null;

    tony = third; // OK.

    不当铸件:

    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.

    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

    }

    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具有指针算术。但是,我们没有在Java。

    更多相关内容
  • 主要介绍了Java中避免空指针异常的方法,本文讨论Optional类型、Objects类等技术,需要的朋友可以参考下
  • JAVA指针

    千次阅读 2021-02-12 23:37:29
    首先,提个问题:JAVA中没有指针JAVA中有指针,哪个一个对呢?答:都对,JAVA中没有指针,因为我们不能对指针直接操作,像C++那样用->来访问变量。JAVA指针,因为JDK中封装了指针。(现在我们就来找到这个指针...

    首先,提个问题:JAVA中没有指针,JAVA中有指针,哪个一个对呢?

    答:都对,JAVA中没有指针,因为我们不能对指针直接操作,像C++那样用->来访问变量。

    JAVA有指针,因为JDK中封装了指针。(现在我们就来找到这个指针)

    我的理解:

    在声明一个对象的时候,其实就是定义了一个指针变量。

    注意:

    1、指针变量有两层含义

    1) 指针变量里存的是地址(它指向的变量的首地址)。

    2) 指针变量有类型,类型说明了该指针指向的变量在内存中的范围(大小)。

    2、使用创建一个对象包括声明和定义。

    1) 声明是指定义一个指向该对象的指针变量。

    2) 定义是指用new关键字在堆内存中创建了对象,并把他的首地址付给那个指针变量。

    这样,很多概念就很容易理解了。

    一、值传递和引用传递

    举例说明:

    测试程序为:

    public class Student {

    String name;

    }

    public class TestClass {

    public static void main(String[] args) {

    Student stu1;

    stu1 = new Student();

    stu1.name = "小明";

    int a = 10;

    System.out.println("改变前,stu1名字为" + stu1.name);

    System.out.println("改变前,a的值为" + a);

    TestClass myTest = new TestClass();

    myTest.change(a, stu1);

    System.out.println("改变后,stu1名字为" + stu1.name);

    System.out.println("改变后,a的值为" + a);

    }

    void change(int num, Student student) {

    num = num + 10;

    student.name = "小强";

    }

    }

    运行结果为:

    改变前,stu1名字为小明

    改变前,a的值为10

    改变后,stu1名字为小强

    改变后,a的值为10

    在内存中的表示如下:

    转变前:

    714096c0611f9986b5c55db58e0542b3.png

    JAVA与指针

    转变时:把stu1的值(36DF)传给student,使student指向36DF。小明变成了小强。

    把a的值10传给了num,使num变成了20。JAVA与指针

    转变后:student和num两个变量被销毁。

    JAVA与指针

    所以,stu1指向的内容改变了,a的值不变。这也就是值传递与引用传递的区别。从中也可以看出就把Student stu1;理解成声明了一个指向Student类的指针变量就可以了。

    这里只用String这个类特殊。

    public class TestClass {

    public static void main(String[] args) {

    String name = "abc";

    System.out.println(name);

    TestClass myTest = new TestClass();

    myTest.change(name);

    System.out.println(name);

    }

    void change(String str) {

    str = "abcd";

    }

    }

    运行结果为:

    改变前name为abc

    改变前name为abc

    按照前面的分析改变后的结果应该为:abcd,如图:JAVA与指针

    198a676e4100eeb0d9a9b5d68accba16.png

    但是你会发现问题,上文强调过指针的第二层含义为定义了变量在堆内存中的范围也就是name指向的变量只能为三个字母的范围,把name付给str,str也只能指向三个字母范围的变量,“abcd”超出了范围。(其实改为大小相同的“abd”也不行)

    所以JAVA引入了一个字符串池的概念。就是说它会把所已知的字符串放入字符串池,如果你创建新字符串没有使用new关键字,它首先会去字符串池找有没有相同值的字符串,如果有的话就指向它;如果没有的话就会创建新的空间。

    所以在内存中应该为:

    JAVA与指针

    583662b243885f537ec1e123f40682bb.png

    二、父类与子类

    举个例子,定义一个Father类,一个Son类,测试

    public class Father {

    String name;

    Father(String name) {

    System.out.println("Father一个参数构造函数");

    this.name = name;

    }

    void drive() {

    System.out.println("骑自行车");

    }

    }

    public class Son extends Father {

    Son(String name) {

    super(name);

    System.out.println("Son一个参数构造函数");

    this.name = name;

    }

    @Override

    void drive() {

    System.out.println("开宝马");

    }

    void QQ() {

    System.out.println("聊QQ");

    }

    }

    public class Test {

    public static void main(String[] args) {

    Father son1 = new Son("小毛");

    son1.drive();

    }

    }

    结果为:

    Father一个参数构造函数

    Son一个参数构造函数

    开宝马

    内存分析:

    son1为Father类的指针,但new了一个Son类的对象,并把这个对象付给了son1。

    JAVA与指针

    ad94e51559510b6ab7ea0a0639caac42.png

    当new一个子类对象(构造子类对象)的时候,需要先创建父类对象,也就是要调用父类的默认构造函数(无参构造函数),如果父类没有无参构造函数也就是说他的无参构造函数被你重写了,那么子类也不能有无参的构造方法,并且在子类的有参构造方法中必须指明构造父类的构造方法(用Super关键字)。

    展开全文
  • Optional可以让你的代码具有可读性,且会避免出现空指针异常。下面这篇文章主要给大家介绍了关于利用Java8 Optional如何避免空指针异常的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
  • 前言 在网上大家很多都看到过这样一句话:“JVM内存最好不要超过32G”。 今天我们就来分析一下为...对象头,又包括三部分:MarkWord、元数据指针、数组长度。 下面图是64位系统下的对象头布局 MarkWord:用于存储对象

    前言

    在网上大家很多都看到过这样一句话:“JVM内存最好不要超过32G”。
    今天我们就来分析一下为什么?32G到底是怎么算出来的。

    JAVA对象模型

    我们先了解一下,一个JAVA对象的存储结构。在Hotspot虚拟机中,对象在内存中的存储布局分为 3 块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。
    在这里插入图片描述

    1、对象头(Header)

    对象头,又包括三部分:MarkWord、元数据指针、数组长度。
    下面图是64位系统下的对象头布局

    MarkWord:用于存储对象运行时的数据,比如HashCode、锁状态标志、GC分代年龄等。这部分在64位操作系统下,占8字节(64bit),在32位操作系统下,占4字节(32bit)。
    具体的作用可以参考我之前写的synchronized锁原理分析(一、从Java对象头看synchronized锁的状态)

    指针:对象指向它的类元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。
    这部分就涉及到一个指针压缩的概念,在开启指针压缩的情况下,占4字节(32bit),未开启情况下,占8字节(64bit),现在JVM在1.6之后,在64位操作系统下都是默认开启的。

    数组长度:这部分只有是数组对象才有,如果是非数组对象,就没这部分了,这部分占4字节(32bit)。
    java对象头

    2、实例数据(Instance Data)

    用于存储对象中的各种类型的字段信息(包括从父类继承来的)。

    3、对齐填充(Padding)

    java对象的大小默认是按照8字节对齐,也就是说java对象的大小必须是8字节的倍数。如果算到最后不够8字节的话,那么就会进行对齐填充。
    那么为什么非要进行8字节对齐呢?这样岂不是浪费了空间资源?

    Scott oaks在书上给出的理由是:
    其实在JVM中(不管是32位的还是64位的),对象已经按8字节边界对齐了;对于大部分处理器,这种对齐方案都是最优的。所以使用压缩的oop并不会损失什么。如果JVM
    中的第一个对象保存到位置0,占用57字节,那下一个对象就要保存到位置64,浪费了7
    字节,无法再分配。这种内存取舍是值得的(而且不管是否使用压缩的oop,都是这样),因为在8字节对齐的位置,对象可以更快地访问。
    不过这也是为什么JVM没有尝试模仿36位引用(可以访问64GB的内存)的原因。在那种情况下,对象就要在16字节的边界上对齐,在堆中保存压缩指针所节约的成本,就被为对齐对象而浪费的内存抵消了。

    也就说,8字节对齐,是为了效率的提升,以空间换时间的一种方案。当然你还可以16字节对齐。但是8字节是最优选择。

    指针压缩原理

    为什么对象指针,可以用8字节存也可以用4字节存?4字节存不会有什么问题吗?

    1、不开启指针压缩

    首先,我们来分析如果不开启指针压缩的情况下是,java对象是怎么存储的

    在这里插入图片描述

    采用8字节(64位)存储真实内存地址,比之前采用4字节(32位)压缩存储地址带来的问题:

    1. 增加了GC开销:64位对象引用需要占用更多的堆空间,留给其他数据的空间将会减少,
      从而加快了GC的发生,更频繁的进行GC。

    2. 降低CPU缓存命中率:64位对象引用增大了,CPU能缓存的oop将会更少,从而降低了CPU缓存的效率。

    2、开启指针压缩

    既然64位存储内存地址,会导致了这么多问题,那么我们可以不可以找一种方法,既使用之前的4字节(32位)存指针地址,又可以扩大内存的方法呢?

    答案就是采用指针压缩技术!!

    4个字节,32位,可以表示232 个地址,如果这个地址是真实内存地址的话,那么由于CPU寻址的最小单位是byte,也就是 232 byte = 4GB。

    如果内存地址是指向 bit的话,32位的最大寻址范围其实是 512MB,但是由于内存里,将8bit为一组划分,所以内存地址就其实是指向的8bit为一组的byte地址,所以32位可以表示的容量就扩充了8倍,就变成了4GB。

    上面这个原理一定要明白,才能理解下面的指针压缩原理,不明白可以先看一下我的这篇文章。

    32位CPU最多支持4G内存是怎么算出来的?(解惑篇)

    看完上面的文章之后,继续往下进行。

    4字节,8位最大表示4GB内存。那么Java是怎么做到 4个字节表示32GB呢?怎有扩大了8倍???

    这就要使用到之前提到的Java的对齐填充机制了。
    Java的8字节对齐填充,就像是内存的8bit为一组,变为1byte一样。
    这里的压缩指针,不是真实的操作系统内存地址,而是Java进行8byte映射之后的地址,所以也相对于操作系统的指针有进行的8倍的扩容。

    看下图:
    JVM就将堆内存进行了块划分,以8字节为最小单位进行划分。
    在这里插入图片描述
    将java堆内存进行8字节划分

    java对象的指针地址就可以不用存对象的真实的64位地址了,而是可以存一个映射地址编号。
    这样4字节就可以表示出2^32个地址,而每一个地址对应的又是8byte的内存块。
    所以,再乘以8以后,一换算,就可以表示出32GB的内存空间。

    这里很巧妙的运用了java对齐填充的特性,通过映射的方式达到了内存扩充的效果。

    想一想?这里运用的原理是不是和操作系统32位表示4GB内存的原理一毛一样!!!
    我想着也是java做对齐填充的一重大原因吧!!

    也就解释了为什么当内存大于32GB时,开启指针压缩的参数会失效!
    所以也网上建议大家在64位系统系下,JAVA的堆内存设置最好不要超过32G,一旦超过32G后,指针压缩就会失效,然后带来GC的触发频次变高,而且造成空间浪费。

    注意:
    32G是个近似值,这个临界值跟JVM和平台有关,当我们线上真正启动服务的时候直接设置 -Xmx=32GB 的时候很可能导致 CompressedOop 失效,那我们怎么确定当前环境下最大内存设置多大才且最大限度的使用内存才能启动 CompressedOop 呢?我们可以通过增加JVM参数 -XX:+PrintFlagsFinal,验证UseCompressedOops的值,从而得知,到底是不是真的开启了压缩指针,还是压缩指针失效!

    展开全文
  • Java中的"指针

    千次阅读 2021-03-07 05:35:02
    Java语言有一个优点就是它相对其他编程语言(例如C语言)摒弃了指针的数据类型,但是否真的摒弃了还得仔细研究一下java的内部机制。Java中的堆栈Java堆栈都在Ram中,与其他一些语言不同的是这些堆栈一部分是由Java中的...

    Java语言有一个优点就是它相对其他编程语言(例如C语言)摒弃了指针的数据类型,但是否真的摒弃了还得仔细研究一下java的内部机制。

    Java中的堆栈

    Java堆栈都在Ram中,与其他一些语言不同的是这些堆栈一部分是由Java中的JVM通过算法自动管理,方便了许多。

    Java中当一个方法执行时,会建立相应的内存栈(栈是一段连续的内存空间),里面存放的是方法中的基本类型的变量数据和对象的引用变量

    当Java执行new语句时会建立相应堆内存(堆是一片随机的内存空间),里面存放new出来的对象

    Java中的"指针"就是这两个内存区域通过变量映射出的对应关系。

    之前说开辟栈内存中,里面存放的数据类型有基本类型的变量数据和对象的引用变量,这个引用变量就是"指针"

    public class TestObject{

    public TestObject(){

    System.out.println("Hello World!");

    }

    }

    public class Test{

    public static void main(String[] arge){

    int a=10;

    TestObject testObj = new TestObject();

    }

    }

    上述代码的内存分配为

    a98332f1413a?utm_campaign=maleskine&utm_content=note&utm_medium=seo_notes&utm_source=recommendation

    testObj就是Java中的“指针”,它指向堆内存中一块为TestObject对象随机分配的一片内存空间的地址,从而达到一种引用效果,这就是Java中的引用类型。

    展开全文
  • Java中的空指针异常

    千次阅读 2021-11-25 14:56:31
    1.1 异常的分类1.2 空指针异常引入1.3 空指针异常说明二、Java中的null三、空指针产生的常见情况及避免办法3.1 字符串常量未初始化,比较时导致空指针异常3.2 接口类型的对象没有使用具体的类进行初始化导致空指针...
  • Java中有指针么?

    千次阅读 2022-03-10 16:02:18
    因为JAVA中没有学过指针。那么什么是指针呢? 指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(Pointed to)存在电脑存储器中另一个地方的值。也就是通过地址可以找到所需的变量单元,可以说,...
  • 什么是java空指针异常我们都知道java是没有指针的,这里说的"java指针"指的就是java的引用,我们不在这里讨论叫指针究竟合不合适,而只是针对这个异常本身进行分析。空指针就是空引用,java空指针异常就是引用本身为...
  • 来源:blog.csdn.net/qq_44543508/article/details/94589868java.lang.NullPointerException出现的几种原因:1、字...
  • Java 中空指针处理方法

    千次阅读 2021-02-27 19:08:28
    指针异常(Null Pointer Exception)是我们平时最容易碰到的,也是最令人讨厌的异常。本文介绍如何避免出现空指针异常。首先我们看如下的示例:private Boolean isFinished(String status) {if (status....
  • java中到底有没有指针(转)

    千次阅读 2021-02-27 16:53:21
    学过c/c++,然后学java的人往往心中有此纠结,java中到底有没有指针?如果一定要在是或否里选择一个,OK,java中没有指针。那么,java中的引用(reference)和c/c++中的指针(如无特别说明,后文指针均指c/c++中的指针)...
  • Java指针异常和解决办法

    千次阅读 2022-04-19 20:37:21
    目录问题描述:尝试1:尝试2:使用Optional防止出现空指针异常引用 问题描述: public class Main20220419 { public static void main(String[] args) { String id = null; Item item = ItemService.getItemById...
  • Java指针碰撞简介

    千次阅读 2020-05-23 15:32:42
    一. 问题背景 在了解TLAB的来源时涉及指针碰撞 此笔记仅供自己参考,如有错误请指正 二. 指针碰撞 2.1 简介 2.2 碰撞的可能情况 还有其他情况不一一详述,在此只是为了表达什么是指针碰撞而已 ...
  • 假设以带头结点的循环链表表示一个队列,并且只设一个队尾指针指向尾元素结点(注意不设头指针),试出相应的置空队、入队、出队的算法。(Java描述)
  • 指针:针对对象类型,对象在堆中分配“房子”。空指针(null)的对象没有分配到“房子”,所以,无法使用该对象。 使用任何的对象数据时,都要进行空指针判断。 通用的方式有三种: (1)null显式判断 (2)...
  • java真的有指针吗?

    2021-03-19 09:46:08
    在内部,对象的引用被实现为指针。虽然没有指针算法......C++有指针,因为它是作为C的超集构建的,...这是白皮书The Java Language Environment的摘录:2.2.9 No More PointersMost studies agree that pointers ar...
  • 文章目录前言1....相比C语言,Java中的“引用数据类型”,和C语言中的“指针”比较相似,所以这里将两者进行对比分析。 1. Java中“基本数据类型”和“引用数据类型”变量在内存分配时的不同 对于“基本
  • 经过几天的奋战,终于让我搞懂了JNA的解析以及指针在结构体中的应用!!!下了很多的资料,里面包含c++的.h头文件,给需要帮助的人看看!! 里面包含代码以及解析过程。
  • Java基础(1)-存在指针

    千次阅读 多人点赞 2018-09-28 13:21:47
    许多刚接触Java语言的朋友可能会认为java没有指针(*),加上许多入门教程为了便于初学者理解而去解释说Java不存在像C/CPP那样的指针操作,所以java没有指针这样的认识就产生了,但答案...本文将对java指针做一基本讲解。
  • java指针异常(NullPointerException) java指针异常(NullPointerException)
  • 算法学习之双指针(java版)

    千次阅读 2020-07-10 21:29:44
    算法学习之双指针(java版) 数组或字符串相关的问题经常需要运用双指针来求解。而双指针又分为快慢指针和左右指针。其中快慢指针主要用于解决链表问题,而左右指针用于解决数组问题。 概念 快慢指针 顾名思义,快慢...
  • 关于Java:捕获空指针异常

    千次阅读 2021-03-08 05:51:18
    我想问的是有关Java的多数知识,但我想它适用于许多语言。考虑,if(myVariable==null){doSomethingAboutIt();}else carryOn(myVariable);和try{carryOn(MyVariable);}catch(NullPointerException e ){...
  • Java中指针

    2021-04-13 15:55:29
    指针为C/C++语言的特色,在C语言中:&为取地址符合,指向内存单元的地址。 例: #include<stdio.h> int main() { int a=1; printf("a 的值:%d\n",a); printf("a 的地址:%d\n",&a); return 0; } /...
  • java指针异常解决Java programming language provides the Null Pointer Exception type in order to handle object creation related errors and misuse. In this tutorial, we will learn what is Null Pointer ...
  • java避免空指针异常 空指针异常是Java中最常见,最烦人的异常。 在这篇文章中,我想避免这种不希望的异常。 首先让我们创建引发空指针异常的示例 private Boolean isFinished(String status) { if (status....
  • Java指针异常的几种情况

    千次阅读 2020-05-11 23:42:44
    Java指针异常的几种情况 NullPointerException 说法一 NullPointerException由RuntimeException派生出来,是一个运行级别的异常。意思是说可能会在运行的时候才会被抛出,而且需要看这样的运行级别异常是否会...
  • Java 中的“函数指针

    万次阅读 2018-02-13 12:07:10
    最近登陆上来发现竟然有这么多人看我过的博文,虽然的也不怎么好,所以打算后面好好的一些东西,养成习惯吧。最近又重新看了比较新的《Java核心卷 第十版》,发现了值得记录的一些内容,这里就结合我自己的...
  • Java对象的内存布局与压缩指针原理

    千次阅读 2020-06-20 19:24:05
    对象头由两部分组成:一部分是Markword,另一部分是类型指针; Markword在32位操作系统中占用4字节,在64位操作系统中占用8字节。 下图是Markword在32位系统中的存储示例: 从图中可见,在32位地址的Markword中,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 580,878
精华内容 232,351
关键字:

java指针怎么写

java 订阅