-
2022-03-10 16:02:18
指针的概念对于没有学过C语言的朋友是很陌生的。因为JAVA中没有学过指针。那么什么是指针呢?
- 指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(Pointed to)存在电脑存储器中另一个地方的值。也就是通过地址可以找到所需的变量单元,可以说,地址指向该变量单元。
那么Java中有没有指针呢?
有很多学Java的小伙伴可能会说:“Java中哪里有指针呢?我见都没见过”。
确实,Java中没有指针的概念,但是学过c语言的小伙伴很快就会有新的疑惑——“如果Java不存在指针的话,那么是如何实现复杂的数据结构?”事实上,Java可以说处处存在指针!
JAVA中的对象类型本质上应该叫做 对象指针 类型。那么传统的对象类型呢?在JAVA里已经不见了踪影! 既然没有了传统的对象类型,那么对象指针变量 前面的也就可以不要了。对象指针变量也就可以简称为对象变量了, 反正也不会和其它概念混淆!
所有的对象变量都是指针,没有非指针的对象变量,想不用指针都不行,这就是指针的泛化和强化。
不叫指针了,就叫对象变量,这就是概念上的淡化和弱化。 没有了指针的加减运算,也没有了*、->等运算符,这是对指针的简单化。虽然没有指针的名但有指针的实。
所以JAVA没有表面看起来的那么简单, 深深的钻研进去, 才能把它学透。
更多JAVA教程:
最后Java基础入门的小伙伴,技术整合提升自己不要错过
需要课件、源码、安装包等资料,可以评论告诉我哦~
更多相关内容 -
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
在内存中的表示如下:
转变前:
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与指针
但是你会发现问题,上文强调过指针的第二层含义为定义了变量在堆内存中的范围也就是name指向的变量只能为三个字母的范围,把name付给str,str也只能指向三个字母范围的变量,“abcd”超出了范围。(其实改为大小相同的“abd”也不行)
所以JAVA引入了一个字符串池的概念。就是说它会把所已知的字符串放入字符串池,如果你创建新字符串没有使用new关键字,它首先会去字符串池找有没有相同值的字符串,如果有的话就指向它;如果没有的话就会创建新的空间。
所以在内存中应该为:
JAVA与指针
二、父类与子类
举个例子,定义一个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与指针
当new一个子类对象(构造子类对象)的时候,需要先创建父类对象,也就是要调用父类的默认构造函数(无参构造函数),如果父类没有无参构造函数也就是说他的无参构造函数被你重写了,那么子类也不能有无参的构造方法,并且在子类的有参构造方法中必须指明构造父类的构造方法(用Super关键字)。
-
Java中避免空指针异常的方法
2020-09-04 03:34:56主要介绍了Java中避免空指针异常的方法,本文讨论Optional类型、Objects类等技术,需要的朋友可以参考下 -
利用Java8 Optional如何避免空指针异常详解
2020-08-28 07:01:57Optional可以让你的代码具有可读性,且会避免出现空指针异常。下面这篇文章主要给大家介绍了关于利用Java8 Optional如何避免空指针异常的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。 -
如何在Java中使用指针?
2021-02-27 17:20:47Java中的所有对象都是引用,您可以像使用指针一样使用它们。abstract class Animal{...}class Lion extends Animal{...}class Tiger extends Animal{public Tiger() {...}public void growl(){...}}Tiger first = ...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
请注意,以其他方式给second赋值(NULL,new ...)同样是潜在的错误,并可能导致丢失其指向的对象。
OutOfMemoryError当您调用new并且分配器无法分配所请求的单元格时,Java系统将引发异常()。这是非常罕见的,通常是由于失控的递归导致的。
请注意,从语言的角度来看,将对象放弃到垃圾回收器根本不是错误。这只是程序员需要注意的事情。相同的变量可以在不同的时间指向不同的对象,并且当没有指针引用它们时,旧值将被回收。但是,如果程序的逻辑要求维护对对象的至少一个引用,则将导致错误。
新手经常会犯以下错误。
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中的空指针异常
2021-11-29 16:28:28Java中的空指针异常 一、什么是空指针异常? 三、空指针产生的常见情况及避免办法 3.1 字符串常量未初始化,比较时导致空指针异常 3.2 接口类型的对象没有使用具体的类进行初始化导致空指针异常 3.3 参数...Java中的空指针异常
- 一、什么是空指针异常?
- 三、空指针产生的常见情况及避免办法
-
- 3.1 字符串常量未初始化,比较时导致空指针异常
- 3.2 接口类型的对象没有使用具体的类进行初始化导致空指针异常
- 3.3 参数类型为包装类型,使用时自动拆箱导致空指针异常
- 3.4 对象为空,但未判空导致空指针异常
- 3.5 对key、value不能为null的容器put为null的key、value值导致空指针异常
- 3.6 方法或者远程服务返回的list不是空而是null,没有进行判空,就直接调用该list的方法导致空指针异常
一、什么是空指针异常?
1.1 异常的分类
NullPointerException是RuntimeException的一个子类,这是运行时异常,在编译时期不会触发。
1.2 空指针异常引入
Java是没有指针的,所以我们常说"Java 指针"就是指"Java 的引用"。
空指针就是空引用
,Java空指针异常就是引用本身为空,但却调用了方法,这个时候就会出现空指针异常。成员变量和方法是属于对象的(除去静态的),在对象中才存在相对应的成员变量和方法,然后通过对象去调用这些成员变量和方法。
而对于空指针来说,它是不指向任何对象的,也就是
没有所谓的成员变量和方法
,这个时候去调用某些属性和方法时,就一定会出现空指针异常。1.3 空指针异常说明
/** * @author QHJ * @date 2021/11/25 14:42 * @description: */ public class NullPointTest { private int a = 1; private int b = 2; public static void main(String[] args) { NullPointTest nullPointTest1 = new NullPointTest(); System.out.println(nullPointTest1.a); System.out.println(nullPointTest1.sum()); NullPointTest nullPointTest2 = null; System.out.println(nullPointTest2.b); System.out.println(nullPointTest2.sum()); } public String sum(){ return "这是sum()方法..."; } }
说明:对象 nullPointTest1 是通过默认的无参构造方法实例出来的 NullPointTest 对象;对象 nullPointTest2 只是声明了一个空对象,并没有指向实际的对象,它没有响应的成员变量和方法,当调用不属于它的成员变量和方法时,引发空指针异常。
二、Java中的null
null是Java中一个很重要的概念,null 设计的初衷是为了表示一些缺失的东西,比如缺失的用户、资源或一些其他东西。
-
首先,
null是关键字
,像public、static、final。它是大小写敏感的,你不能将 null 写成 Null 或 NULL,编译器将不能识别它们然后报错。 -
null是任何引用类型的默认值
,不严格的说是所有object类型的默认值。就像你创建了一个布尔类型的变量,它将 false 作为自己的默认值,Java中的任何引用变量都将 nul l作为默认值。这对所有变量都是适用的,如成员变量、局部变量、实例变量、静态变量(但当你使用一个没有初始化的局部变量,编译器会警告你)。 -
null既不是对象也不是一种类型,它仅是一种特殊的值,你可以将其赋予任何引用类型,你也可以将 null 转化成任何类型。
-
null可以赋值给引用变量,但不能将null赋给基本类型变量。
例如int、double、float、boolean。编译器将会报错。当直接将null赋值给基本类型,会出现编译错误。但是如果将null赋值给包装类object,然后将object赋给各自的基本类型,编译器不会报,但是你将会在运行时期遇到空指针异常。这是Java中的自动拆箱导致的。
-
任何含有null值的包装类在Java拆箱生成基本数据类型时候都会抛出一个空指针异常。
-
如果使用了带有 null 值的引用类型变量,instanceof 操作将会返回 false。
Integer iAmNull = null; if(iAmNull instanceof Integer){ System.out.println("iAmNull is instance of Integer"); }else{ System.out.println("iAmNull is NOT an instance of Integer"); } 结果:iAmNull is NOT an instance of Integer
-
不能调用非静态方法来使用一个值为 null 的引用类型变量。但是可以调用静态方法里值为 null 的引用类型变量,因为静态方法使用静态绑定,不会抛出空指针异常。
-
可以将 null 传递给方法使用,这时方法可以接收任何引用类型
,例如public void print(Object obj)可以这样调用print(null)。从编译角度来看这是可以的,但结果完全取决于方法。null 安全的方法,如在这个例子中的 print() 方法,不会抛出空指针异常,只是优雅的退出。如果业务逻辑允许的话,推荐使用 null 安全的方法。 -
可以使用 = = 或者 != 操作来比较 null 值
,但是不能使用其他算法或者逻辑操作,例如小于或者大于。在Java中 null == null 将返回true。
三、空指针产生的常见情况及避免办法
3.1 字符串常量未初始化,比较时导致空指针异常
-
出现空指针
String str = null; // 不推荐——把变量放在常量前,当变量为空时,运行时报空指针 if (str.equals("zhangsan")){ System.out.println("相等"); }else{ System.out.println("不相等"); }
-
避免空指针
String str = null; // 推荐——把常量放在变量前,运行时不会报错 if ("zhangsan".equals(str)){ System.out.println("相等"); }else { System.out.println("不相等"); }
3.2 接口类型的对象没有使用具体的类进行初始化导致空指针异常
-
出现空指针
// list1 没有使用具体的类进行初始化,在使用时会报错 List list1; // list2 没有使用具体的类进行初始化,报空指针 List list2 = null; System.out.println("不能直接使用list1..."); System.out.println("list2:" + list2.isEmpty());
-
避免空指针
List list3 = new ArrayList(); System.out.println("list3:" + list3.isEmpty());
3.3 参数类型为包装类型,使用时自动拆箱导致空指针异常
-
出现空指针
Integer a = 1; Integer b = null; sum(a, b); public static String sum(Integer a, Integer b){ System.out.println(a + b); return "这是sum()方法..."; }
注意: null 值不能转换为基本数据类型!
-
避免空指针
Integer a = 1; Integer b = null; // 避免空指针——及时判空 if (a != null && b != null){ sum(a, b); }else{ System.out.println("参数不允许为空值!"); } public static String sum(Integer a, Integer b){ System.out.println(a + b); return "这是sum()方法..."; }
3.4 对象为空,但未判空导致空指针异常
-
出现空指针
UserEntity userEntity = null; System.out.println(userEntity.getName() + "\t" +userEntity.getAge());
-
避免空指针
UserEntity userEntity = null; if (userEntity != null){ System.out.println(userEntity.getName() + "\t" +userEntity.getAge()); }else { System.out.println("对象不能为空哦!"); }
3.5 对key、value不能为null的容器put为null的key、value值导致空指针异常
-
出现空指针
Map<String, String> map = new Hashtable<>(); map.put("name:", "张三"); map.put("age:", "23"); map.put("nick:", null); map.put("", ""); System.out.println(map);
-
避免空指针
Map<String, String> map = new HashMap<>(); map.put("name:", "张三"); map.put("age:", "23"); map.put("nick:", null); map.put("", ""); System.out.println(map);
3.6 方法或者远程服务返回的list不是空而是null,没有进行判空,就直接调用该list的方法导致空指针异常
-
出现空指针
// 假设是通过方法或远程调用获得的list List list = null; Stream stream = list.stream().filter(s -> s.equals("zhangsan")); System.out.println(stream);
-
避免空指针
// 假设是通过方法或远程调用获得的list List list = null; if (list != null){ Stream stream = list.stream().filter(s -> s.equals("zhangsan")); System.out.println(stream); }else { System.out.println("获取的集合list不能为空!"); }
四、总结和技巧
在遇到空指针错误时,要重点关注报错发生的所在行,通过空指针异常产生的两条主要原因(变量未初始化和对象为空)诊断具体的错误,主要注意以下几点:
初始化 避免在函数中返回 null 值 判空处理 "常量在前变量在后" 使用 valueOf() 替换toString()
Java中的8种数据类型,变量的值可以有其默认值,假如没有对其正常赋值,Java虚拟机是不能正确编译通过的,所以使用基本数据类型一般是不会引起空指针异常的。也就是说,在实际开发中大多数的空指针异常主要与对象的操作相关。
-
JAVA虚拟指针仪表类
2019-02-18 21:10:37java代码编写的虚拟指针仪表控件。直接在定时函数中对仪表实时数据赋值即可动态刷新。 -
Java中的"指针
2021-03-07 05:35:02Java语言有一个优点就是它相对其他编程语言(例如C语言)摒弃了指针的数据类型,但是否真的摒弃了还得仔细研究一下java的内部机制。Java中的堆栈Java堆栈都在Ram中,与其他一些语言不同的是这些堆栈一部分是由Java中的... -
Java字符串比较方法equals的空指针异常的解决
2020-08-25 14:12:09主要介绍了Java字符串比较方法equals的空指针异常的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 -
java.lang.NullPointerException 如何处理空指针异常的实现
2020-08-25 08:16:53主要介绍了java.lang.NullPointerException 如何处理空指针异常的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 -
java 中的指针_Java中的指针
2020-06-24 21:15:52java 中的指针 Java中有指针吗? 简短的答案是“不,没有”,这对于许多开发人员来说似乎是显而易见的。 但是,为什么对其他人却不那么明显呢? ... -
java中到底有没有指针(转)
2021-02-27 16:53:21学过c/c++,然后学java的人往往心中有此纠结,java中到底有没有指针?如果一定要在是或否里选择一个,OK,java中没有指针。那么,java中的引用(reference)和c/c++中的指针(如无特别说明,后文指针均指c/c++中的指针)... -
【Java】Java中的“引用类型”和C中的“指针”区别
2022-03-13 18:44:23文章目录前言1....相比C语言,Java中的“引用数据类型”,和C语言中的“指针”比较相似,所以这里将两者进行对比分析。 1. Java中“基本数据类型”和“引用数据类型”变量在内存分配时的不同 对于“基本 -
java空指针异常解决_Java中的空指针异常是什么以及如何解决?
2020-10-04 23:59:11java空指针异常解决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空指针异常和解决办法
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空指针异常:java.lang.NullPointException
2021-03-09 15:23:05什么是java空指针异常我们都知道java是没有指针的,这里说的"java指针"指的就是java的引用,我们不在这里讨论叫指针究竟合不合适,而只是针对这个异常本身进行分析。空指针就是空引用,java空指针异常就是引用本身为... -
Java中空指针异常出现的几种原因以及解决办法!
2021-05-18 00:15:30来源:blog.csdn.net/qq_44543508/article/details/94589868java.lang.NullPointerException出现的几种原因:1、字... -
java避免空指针异常_避免Java中的空指针异常
2020-06-01 17:45:52空指针异常是Java中最常见,最烦人的异常。 在这篇文章中,我想避免这种不希望的异常。 首先让我们创建引发空指针异常的示例 private Boolean isFinished(String status) { if (status.equalsIgnoreCase("Finish... -
算法(Java)——双指针
2021-03-12 10:58:02算法中双指针主要包括首尾双指针(对撞双指针),快慢双指针;通过指针的移动解决问题。 -
Java 中空指针处理方法
2021-02-27 19:08:28空指针异常(Null Pointer Exception)是我们平时最容易碰到的,也是最令人讨厌的异常。本文介绍如何避免出现空指针异常。首先我们看如下的示例:private Boolean isFinished(String status) {if (status.... -
在Java8中如何风骚走位的避开空指针异常
2020-08-25 23:16:57主要给大家介绍了关于在Java8中如何风骚走位的避开空指针异常的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Java8具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧 -
Java中的引用与C中的指针
2021-12-16 09:56:53C语言的指针还可以指向指针,以及指向指向指针的指针(因为指针就是一个值,也要存在内存中,所以它也有一个内存地址) 指针这个东西,只关心内存的地址,不关心内存存的是什么东西,如果该地址中的对象被搬走了,... -
关于java空指针报错(NullPointException)
2022-04-07 17:42:24关于java的空指针报错: 最常见的空指针报错是因为在一个类的对象指针创建之后再调用它,没有给他分配空间,直接调用这个对象的方法或者数据,当然这个说起来还是很简单的,大部分的人都不会犯这样的错误,但是在... -
Java8中Stream使用的一个注意事项
2020-08-28 21:04:26最近在工作中发现了对于集合操作转换的神器,java8新特性 stream,但在使用中遇到了一个非常重要的注意点,所以这篇文章主要给大家介绍了关于Java8中Stream使用过程中的一个注意事项,需要的朋友可以参考借鉴,下面... -
对Java空指针异常的思考
2021-02-26 12:56:25开发了一些Java应用后,发现空指针异常是个很头疼的问题,明明自己在本地已经调试OK了,可是代码在其他环境会莫名其妙的报错,而且还很难定位到具体的异常位置。空指针异常产生的原因,大概是以下几点原因:1、把... -
Java:通过指针传递参数
2021-02-12 17:27:26使用指针运算符取得传入地址单元中的值,将该地址单元中的值进行交换。 在main0()函数的第10行中调用swap0函数时,不能直接将变量i和j作为实参,而要使用取地址运算符“&”将变量i和j的地址传入函数。这样,main... -
Java的指针碰撞简介
2020-05-23 15:32:42一. 问题背景 在了解TLAB的来源时涉及指针碰撞 此笔记仅供自己参考,如有错误请指正 二. 指针碰撞 2.1 简介 2.2 碰撞的可能情况 还有其他情况不一一详述,在此只是为了表达什么是指针碰撞而已 ... -
java中什么是空指针异常以及为什么会产生空指针异常
2020-08-26 15:37:27指针:我所理解的指针指的是java程序中的对象 那什么是空? 举个例子:小明过生日,小华送给了小明一个“礼物”,这个“礼物”只有一个外面的包装但是里面什么都没有,这...