Java中的引用变量
在我们开始使用Reference 变量之前,我们应该了解以下事实。
1.当我们创建一个对象时 (实例)类然后在堆内存中保留空间。让我们通过一个例子来理解。
Demo D1 = new Demo();
现在,堆内存中的空间已创建,但问题是如何访问该空间? .
然后,我们创建一个 Pointing 元素或简称为Reference 变量,它简单地指出对象(在堆内存中创建的空间)。
了解参考变量
1.引用变量用于指向对象/值。
2.类、接口、数组、枚举、注解是Java中的引用类型。引用变量保存Java中引用类型的对象/值。
3.引用变量也可以存储空值。默认情况下,如果没有对象传递给引用变量,那么它将存储一个空值。
4.您可以使用点语法使用引用变量访问对象成员。
例子:
Java
// Java program to demonstrate reference
// variable in java
import java.io.*;
class Demo {
int x = 10;
int display()
{
System.out.println("x = " + x);
return 0;
}
}
class Main {
public static void main(String[] args)
{
Demo D1 = new Demo(); // point 1
System.out.println(D1); // point 2
System.out.println(D1.display()); // point 3
}
}
Java
import java.io.*;
class Demo {
int x = 10;
int display()
{
System.out.println("x = " + x);
return 0;
}
}
class Main {
public static void main(String[] args)
{
// create instance
Demo D1 = new Demo();
// accessing instance(object) variable
System.out.println(D1.x);
// point 3
// accessing instance(object) method
D1.display();
}
}
Java
// Accessing instance methods
import java.io.*;
class Demo {
int x = 10;
int display()
{
System.out.println("x = " + x);
return 0;
}
}
class Main {
public static void main(String[] args)
{
// create instances
Demo D1 = new Demo();
Demo M1 = new Demo();
Demo Q1 = new Demo();
}
}
Java
// Pointing to same instance memory
import java.io.*;
class Demo {
int x = 10;
int display()
{
System.out.println("x = " + x);
return 0;
}
}
class Main {
public static void main(String[] args)
{
// create instance
Demo D1 = new Demo();
// point to same reference
Demo G1 = D1;
Demo M1 = new Demo();
Demo Q1 = M1;
// updating the value of x using G!
// reference variable
G1.x = 25;
System.out.println(G1.x); // Point 1
System.out.println(D1.x); // Point 2
}
}
Java
// Pass by reference and value
import java.io.*;
class Demo {
int x = 10;
int y = 20;
int display(Demo A, Demo B)
{
// Updating value using argument
A.x = 95;
System.out.println("x = " + x);
System.out.println("y = " + y);
return 0;
}
}
class Main {
public static void main(String[] args)
{
Demo C = new Demo();
Demo D = new Demo();
// updating value using primary reference
// variable
D.y = 55;
C.display(C, D); // POINT 1
D.display(C, D); // POINT 2
}
}
Java
// Swapping object references
import java.io.*;
class Demo {
// Swapping Method
int Swap(Demo A, Demo B)
{
Demo temp = A;
A = B;
B = temp;
return 0;
}
}
class Main {
public static void main(String[] args)
{
Demo C = new Demo();
Demo D = new Demo();
// Passing C and reference variables
// to Swap method
C.Swap(C, D);
}
}
Java
import java.io.*;
class Demo {
int arrayUpdate(int[] formalArray)
{
formalArray[2] = 99;
formalArray[4] = 77;
return 0;
}
}
class Main {
public static void main(String[] args)
{
Demo d1 = new Demo();
int[] actualArray = { 1, 2, 3, 4, 5 };
for (int items : actualArray)
System.out.print(items
+ " , "); // printing array
System.out.println();
d1.arrayUpdate(actualArray);
System.out.println();
for (int items : actualArray)
System.out.print(items
+ " , "); // printing array
}
}
Java
// null in java
import java.io.*;
class Demo {
int x = 10;
int display()
{
System.out.println("x = " + x);
return 0;
}
}
class Main {
public static void main(String[] args)
{
Demo obj = null;
// accessing instance(object) method
Kuchbhi.display();
}
}
Demo@214c265e
x = 10
0
让我们一步一步地看看实际发生了什么。
1.当我们创建demo类的对象时new DEMO(); ,调用默认构造函数并返回对象的引用,并且简单地将这个引用存储到引用变量D1 (正如我们所知,关联性是从右侧到左侧)。
2.引用变量的值是一个引用。当我们尝试打印引用变量的值时,输出包含变量的类型和Java为其创建的哈希码:字符串Demo@214c265e告诉我们给定的变量是 Name 类型及其十六进制格式哈希码是 214c265e。
3.此时,我们将使用我们创建的自定义引用变量访问类演示的方法display() 。
BINDING UP : The constructor call returns a value that is a reference to the newly-created object. The equality sign tells the program that the value of the right-hand side expression is to be copied as the value of the variable on the left-hand side. The reference to the newly-created object, returned by the constructor call, is copied as the value of the variable.
Java
import java.io.*;
class Demo {
int x = 10;
int display()
{
System.out.println("x = " + x);
return 0;
}
}
class Main {
public static void main(String[] args)
{
// create instance
Demo D1 = new Demo();
// accessing instance(object) variable
System.out.println(D1.x);
// point 3
// accessing instance(object) method
D1.display();
}
}
10
x = 10
Java
// Accessing instance methods
import java.io.*;
class Demo {
int x = 10;
int display()
{
System.out.println("x = " + x);
return 0;
}
}
class Main {
public static void main(String[] args)
{
// create instances
Demo D1 = new Demo();
Demo M1 = new Demo();
Demo Q1 = new Demo();
}
}
Java
// Pointing to same instance memory
import java.io.*;
class Demo {
int x = 10;
int display()
{
System.out.println("x = " + x);
return 0;
}
}
class Main {
public static void main(String[] args)
{
// create instance
Demo D1 = new Demo();
// point to same reference
Demo G1 = D1;
Demo M1 = new Demo();
Demo Q1 = M1;
// updating the value of x using G!
// reference variable
G1.x = 25;
System.out.println(G1.x); // Point 1
System.out.println(D1.x); // Point 2
}
}
25
25
Note:
Here we pass G1 and Q1 reference variable point out the same object respectively.
Secondly **At Point 1** we try to get the value of the object with G1 reference variable which shows it as **25** and **At Point 2**we try to get the value of an object with D1 reference variable which shows it as **25** as well “” This will prove that the modification in the object can be done by using any reference variable but the condition is it should hold the same reference.
更多关于参考变量
1. 引用变量作为方法参数:
由于原始变量的值直接存储在变量中,而引用变量的值保存对对象的引用。我们还提到用等号赋值会复制右侧的值(可能是某个变量的值)并将其存储为左侧变量的值。类似的复制发生在方法调用期间。无论变量是原始类型还是引用类型,都会将值的副本传递给方法的参数并复制到该参数。
Note: Java only supports pass by value.
但是我们知道引用变量持有实例(OBJECT)的引用,因此引用的副本传递给方法的参数。
例子:
Java
// Pass by reference and value
import java.io.*;
class Demo {
int x = 10;
int y = 20;
int display(Demo A, Demo B)
{
// Updating value using argument
A.x = 95;
System.out.println("x = " + x);
System.out.println("y = " + y);
return 0;
}
}
class Main {
public static void main(String[] args)
{
Demo C = new Demo();
Demo D = new Demo();
// updating value using primary reference
// variable
D.y = 55;
C.display(C, D); // POINT 1
D.display(C, D); // POINT 2
}
}
x = 95
y = 20
x = 10
y = 55
场景一:
场景二:
现在,这里发生了什么,当我们将引用传递给方法时,它将复制到方法签名中定义的引用变量,然后,它们也可以访问对象成员。在这里,我们定义了两个名为C 和 D的实例。之后我们将 C 和 D 传递给进一步引用A 和 B的方法
在点 1: A 将 x 的值从 10 更新为 95,因此 C.display() 将显示 95 20 但在另一个对象 D 中,我们仅将 x 到 D 的值从 y =20 更新为 55,因此 D, display() 将显示 10 和 55。
Note: Any Object Updation will not affect the other object’s member.
2. 如果我们在 Swap Method 的帮助下交换引用变量会怎样?
事实是,如果我们尝试交换引用变量,那么它们只是交换它们的 Pointing 元素,对引用变量的地址和对象(实例)空间没有影响。让我们通过一个例子来理解它:
Java
// Swapping object references
import java.io.*;
class Demo {
// Swapping Method
int Swap(Demo A, Demo B)
{
Demo temp = A;
A = B;
B = temp;
return 0;
}
}
class Main {
public static void main(String[] args)
{
Demo C = new Demo();
Demo D = new Demo();
// Passing C and reference variables
// to Swap method
C.Swap(C, D);
}
}
Here we created, two instances of demo class and passes it to swap method, further those C and D will copy their references to A and B respectively.Before swapping A point to C’s(Object) and B point to D’s(Object). After we perform swapping on A and B, A will now point D’s(Object) and B will Point C’s Object. As described in the figure.
Note: There is no swapping between Variables, They only change their References.
3.如果我们将数组传递给方法,它是否能够更新实际数组的值,即使我们知道数组的副本是对正式数组的传递?
答案是肯定的,这些值将通过形式参数更新,事实是,当我们创建一个数组时,会为所需大小的数组分配一块内存,并返回第一个数组元素的引用,该元素是基数将存储到正式数组(方法参数)的地址。正如我们之前了解到的,每个指向引用变量都可以更改或更新对象。
例子:
Java
import java.io.*;
class Demo {
int arrayUpdate(int[] formalArray)
{
formalArray[2] = 99;
formalArray[4] = 77;
return 0;
}
}
class Main {
public static void main(String[] args)
{
Demo d1 = new Demo();
int[] actualArray = { 1, 2, 3, 4, 5 };
for (int items : actualArray)
System.out.print(items
+ " , "); // printing array
System.out.println();
d1.arrayUpdate(actualArray);
System.out.println();
for (int items : actualArray)
System.out.print(items
+ " , "); // printing array
}
}
1 , 2 , 3 , 4 , 5 ,
1 , 2 , 99 , 4 , 77 ,
4. this 和 super 关键字也是指向元素。
这个关键字。在Java中,这是引用当前对象的引用变量。
super 用于引用直接父类实例变量。我们可以使用 super 关键字来访问父类的数据成员或字段。如果父类和子类具有相同的字段,则使用它。
5.引用变量的空值。
Demo obj = null ;
A.空引用可以设置为任何引用类型变量的值。
B.名称为obj的对象被 nobody 引用。换句话说,对象变成了垃圾。在Java编程语言中,程序员不必担心程序的内存使用。 Java语言的自动垃圾收集器会时不时地清理成为垃圾的对象。如果垃圾收集没有发生,垃圾对象将保留一个内存位置,直到程序执行结束。
Java
// null in java
import java.io.*;
class Demo {
int x = 10;
int display()
{
System.out.println("x = " + x);
return 0;
}
}
class Main {
public static void main(String[] args)
{
Demo obj = null;
// accessing instance(object) method
Kuchbhi.display();
}
}
输出
Exception in thread "main" java.lang.NullPointerException
at Main.main(File.java:17)
Java Result: 1
在这里,我们尝试通过一个指向空(null)的引用变量来访问对象的成员,因此它显示了NullPointerException。现在,如果出现错误,第一步是查找值可能为 null 的变量。幸运的是,错误消息很有用:它告诉了哪一行导致了错误。自己试试吧!