java引用详解

2023-05-16

文章目录

        • 一、关于对象与引用之间的一些基本概念
  • new Vehicle Vehicle veh1
        • 二、Java对象及引用
        • 三、只有理解了对象和引用的关系,才能理解参数传递
        • 总结:
  • 什么是值传递,什么是引用传递。为什么说Java中只有值传递
    • 实参与形参
    • 值传递与引用传递
    • Java中的值传递
    • 总结

学过C/C++的应该都知道,C/C++中存在 值传递、指针传递、引用传递。

在java中存在指针传递、引用传递。

这篇博客讲解一下java中的引用。

一、关于对象与引用之间的一些基本概念

为便于说明,先定义一个类:

class Vehicle {

int passengers;

int fuelcap;

int mpg;

}

有了这个类,就可以用它来创建对象:Vehicle veh1 = new Vehicle(),通常把这条语句的动作称之为创建一个对象,其实,它包含了四个动作:

new Vehicle
Vehicle veh1

我们可以把这条语句拆成两部分:

Vehicle veh1;
veh1 = new Vehicle();

效果是一样的。这样写,就比较清楚了,有两个实体:一是对象引用变量,一是对象本身。

在堆空间里创建的实体,与在数据段以及栈空间里创建的实体不同。尽管它们也是确确实实存在的实体,但是,我们看不见,也摸不着。不仅如此,

我们仔细研究一下第二句,找找刚创建的对象叫什么名字?有人说,它叫“Vehicle”。不对,“Vehicle”是类(对象的创建模板)的名字。

一个Vehicle类可以据此创建出无数个对象,这些对象不可能全叫“Vehicle”。

对象连名都没有,没法直接访问它。我们只能通过对象引用来间接访问对象。

为了形象地说明对象、引用及它们之间的关系,可以做一个或许不很妥当的比喻。对象好比是一只很大的气球,大到我们抓不住它。引用变量是一根绳, 可以用来系汽球。

如果只执行了第一条语句,还没执行第二条,此时创建的引用变量veh1还没指向任何一个对象,它的值是null。引用变量可以指向某个对象,或者为null。

它是一根绳,一根还没有系上任何一个汽球的绳。执行了第二句后,一只新汽球做出来了,并被系在veh1这根绳上。我们抓住这根绳,就等于抓住了那只汽球。

再来一句:

Vehicle veh2;

就又做了一根绳,还没系上汽球。如果再加一句:

veh2 = veh1;

系上了。这里发生了复制行为。但是,要说明的是,对象本身并没有被复制,被复制的只是对象引用。结果是,veh2也指向了veh1所指向的对象。两根绳系的是同一只汽球。

如果用下句再创建一个对象:

veh2 = new Vehicle();

则引用变量veh2改指向第二个对象。

从以上叙述再推演下去,我们可以获得以下结论:

  1. 一个对象引用可以指向0个或1个对象(一根绳子可以不系汽球,也可以系一个汽球)
  2. 一个对象可以有N个引用指向它(可以有N条绳子系住一个汽球)

如果再来下面语句:

veh1 = veh2;

按上面的推断,veh1也指向了第二个对象。这个没问题。问题是第一个对象呢?没有一条绳子系住它,它飞了。多数书里说,它被Java的垃圾回收机制回收了。

这不确切。正确地说,它已成为垃圾回收机制的处理对象。至于什么时候真正被回收,那要看垃圾回收机制的心情了。

由此看来,下面的语句应该不合法吧?至少是没用的吧?

new Vehicle();

不对。它是合法的,而且可用的。譬如,如果我们仅仅为了打印而生成一个对象,就不需要用引用变量来系住它。最常见的就是打印字符串:

System.out.println(“I am Java!”);

字符串对象“I am Java!”在打印后即被丢弃。有人把这种对象称之为临时对象。

对象与引用的关系将持续到对象回收。

二、Java对象及引用

Java对象及引用是容易混淆却又必须掌握的基础知识,本章阐述Java对象和引用的概念,以及与其密切相关的参数传递。

先看下面的程序:

StringBuffer s;
s = new StringBuffer(“Hello World!”);

第一个语句仅为引用(reference)分配了空间,而第二个语句则通过调用类(StringBuffer)的构造函数StringBuffer(String str)为类生成了一个实例(或称为对象)。这两个操作被完成后,对象的内容则可通过s进行访问——在Java里都是通过引用来操纵对象的。

Java对象和引用的关系可以说是互相关联,却又彼此独立。彼此独立主要表现在:引用是可以改变的,它可以指向别的对象,譬如上面的s,你可以给它另外的对象,如:

s = new StringBuffer("Java");

这样一来,s就和它指向的第一个对象脱离关系。

从存储空间上来说,对象和引用也是独立的,它们存储在不同的地方,对象一般存储在堆中,而引用存储在速度更快的堆栈中。

引用可以指向不同的对象,对象也可以被多个引用操纵,如:

StringBuffer s1 = s;

这条语句使得s1和s指向同一个对象。既然两个引用指向同一个对象,那么不管使用哪个引用操纵对象,对象的内容都发生改变,并且只有一份,通过s1和s得到的内容自然也一样,(String除外,因为String始终不变,String s1=”AAAA”; String s=s1,操作s,s1由于始终不变,所以为s另外开辟了空间来存储s)如下面的程序:

StringBuffer s;

s = new StringBuffer(“Java”);

StringBuffer s1 = s;

s1.append(" World");

//打印结果为:s1=Java World
System.out.println(“s1=” + s1.toString());

//打印结果为:s=Java World
System.out.println(“s=” + s.toString());

上面的程序表明,s1和s打印出来的内容是一样的,这样的结果看起来让人非常疑惑,但是仔细想想,s1和s只是两个引用,它们只是操纵杆而已,它们指向同一个对象,操纵的也是同一个对象,通过它们得到的是同一个对象的内容。这就像汽车的刹车和油门,它们操纵的都是车速,假如汽车开始的速度是80,然后你踩了一次油门,汽车加速了,假如车速升到了120,然后你踩一下刹车,此时车速是从120开始下降的,假如下降到60,再踩一次油门,车速则从60开始上升,而不是从第一次踩油门后的120开始。也就是说车速同时受油门和刹车影响,它们的影响是累积起来的,而不是各自独立(除非刹车和油门不在一辆车上)。所以,在上面的程序中,不管使用s1还是s操纵对象,它们对对象的影响也是累积起来的(更多的引用同理)。

三、只有理解了对象和引用的关系,才能理解参数传递

一般面试题中都会考Java传参的问题,并且它的标准答案是Java只有一种参数传递方式:那就是按值传递,即Java中传递任何东西都是传值。如果传入方法的是基本类型的东西,你就得到此基本类型的一份拷贝。如果是传递引用,就得到引用的拷贝。

一般来说,对于基本类型的传递,我们很容易理解,而对于对象,总让人感觉是按引用传递,看下面的程序:

public class ObjectRef {

//基本类型的参数传递 
public static void testBasicType(int m) {  
    System.out.println("m=" + m);//m=50 
    m = 100;  
    System.out.println("m=" + m);//m=100 
}     

//参数为对象,不改变引用的值 ?????? 
public static void add(StringBuffer s) {  
    s.append("\_add");  
}   

//参数为对象,改变引用的值 ????? 
public static void changeRef(StringBuffer s) {  
    s = new StringBuffer("Java"); 
}  
   
public static void main(String\[\] args) {  
    int i = 50;  
    testBasicType(i);  
    System.out.println(i);//i=50 
    StringBuffer sMain = new StringBuffer("init");  
    System.out.println("sMain=" + sMain.toString());//sMain=init 
    add(sMain);  
    System.out.println("sMain=" + sMain.toString());//sMain=init\_add 
    changeRef(sMain);  
    System.out.println("sMain=" + sMain.toString());//sMain=init\_add 
}   

}

以上程序的允许结果显示出,testBasicType方法的参数是基本类型,尽管参数m的值发生改变,但并不影响i。

add方法的参数是一个对象,当把sMain传给参数s时,s得到的是sMain的拷贝,所以s和sMain指向同一个对象,因此,使用s操作影响的其实就是sMain指向的对象,故调用add方法后,sMain指向的对象的内容发生了改变。

在changeRef方法中,参数也是对象,当把sMain传给参数s时,s得到的是sMain的拷贝,但与add方法不同的是,在方法体内改变了s指向的对象(也就是s指向了别的对象,牵着气球的绳子换气球了),给s重新赋值后,s与sMain已经毫无关联,它和sMain指向了不同的对象,所以不管对s做什么操作,都不会影响sMain指向的对象,故调用changeRef方法前后sMain指向的对象内容并未发生改变。

对于add方法的调用结果,可能很多人会有这种感觉:这不明明是按引用传递吗?对于这种问题,还是套用Bruce Eckel的话:这依赖于你如何看待引用,最终你会明白,这个争论并没那么重要。真正重要的是,你要理解,传引用使得(调用者的)对象的修改变得不可预期。

public class Test {

public int i, j;

public void test\_m(Test a) {
Test b = new Test();
b.i = 1;
b.j = 2;
a = b;
}

public void test\_m1(Test a) {
a.i = 1;
a.j = 2;
}

public static void main(String argv\[\]) {
Test t = new Test();
t.i = 5;
t.j = 6;
System.out.println("t.i=" + t.i + "  t.j=" + t.j); // 5,6
t.test\_m(t);
System.out.println("t.i=" + t.i + "  t.j=" + t.j); // 5,6,a和t都指向了一个对象,而在test\_m中s又指向了另一个对象,所以对象t不变!!!
t.test\_m1(t);
System.out.println("t.i=" + t.i + "  t.j=" + t.j); // 1,2
}


}

答案只有一个:Java里都是按值传递参数。而实际上,我们要明白,当参数是对象时,传引用会发生什么状况(就像上面的add方法)?

总结:

如下表达式:

A a1 = new A();

它代表A是类,a1是引用,a1不是对象,new A()才是对象,a1引用指向new A()这个对象。

在JAVA里,“=”不能被看成是一个赋值语句,它不是在把一个对象赋给另外一个对象,它的执行过程实质上是将右边对象的地址传给了左边的引用,使得左边的引用指向了右边的对象。Java表面上看起来没有指针,但它的引用其实质就是一个指针,引用里面存放的并不是对象,而是该对象的地址,使得该引用指向了对象。在Java里,“=”语句不应该被翻译成赋值语句,因为它所执行的确实不是一个赋值的过程,而是一个传地址的过程,被译成赋值语句会造成很多误解,译得不准确。

再如:

A a2;

它代表A是类,a2是引用,a2不是对象,a2所指向的对象为空null;

再如:

a2 = a1;

它代表,a2是引用,a1也是引用,a1所指向的对象的地址传给了a2(传址),使得a2a1指向了同一对象。

综上所述,可以简单的记为,在初始化时,“=”语句左边的是引用,右边new出来的是对象。

在后面的左右都是引用的“=”语句时,左右的引用同时指向了右边引用所指向的对象。

再所谓实例,其实就是对象的同义词。


什么是值传递,什么是引用传递。为什么说Java中只有值传递

关于这个问题,在StackOverflow上也引发过广泛的讨论,看来很多程序员对于这个问题的理解都不尽相同,甚至很多人理解的是错误的。还有的人可能知道Java中的参数传递是值传递,但是说不出来为什么。

在开始深入讲解之前,有必要纠正一下大家以前的那些错误看法了。如果你有以下想法,那么你有必要好好阅读本文。

错误理解一:值传递和引用传递,区分的条件是传递的内容,如果是个值,就是值传递。如果是个引用,就是引用传递。

错误理解二:Java是引用传递。

错误理解三:传递的参数如果是普通类型,那就是值传递,如果是对象,那就是引用传递。

实参与形参

我们都知道,在Java中定义方法的时候是可以定义参数的。比如Java中的main方法:

public static void main(String[] args)

这里面的args就是参数。参数在程序语言中分为形式参数和实际参数。

形式参数:是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数。

实际参数:在调用有参函数时,主调函数和被调函数之间有数据传递关系。在主调函数中调用一个函数时,函数名后面括号中的参数称为“实际参数”。

简单举个例子:

public static void main(String[] args) {
    ParamTest pt = new ParamTest();
    pt.sout("Hollis");//实际参数为 Hollis
}
 
public void sout(String name) { //形式参数为 name
    System.out.println(name);
}

实际参数是调用有参方法的时候真正传递的内容,而形式参数是用于接收实参内容的参数。

值传递与引用传递

上面提到了,当我们调用一个有参函数的时候,会把实际参数传递给形式参数。但是,在程序语言中,这个传递过程中传递的两种情况,即值传递和引用传递。我们来看下程序语言中是如何定义和区分值传递和引用传递的。

值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

有了上面的概念,然后大家就可以写代码实践了,来看看Java中到底是值传递还是引用传递 ,于是,最简单的一段代码出来了:

public static void main(String[] args) {
    ParamTest pt = new ParamTest();
 
    int i = 10;
    pt.pass(i );
    System.out.println("print in main , i is " + i);
}
 
public void pass(int j) {
    j = 20;
    System.out.println("print in pass , j is " + j);
}

上面的代码中,我们在pass方法中修改了参数j的值,然后分别在pass方法和main方法中打印参数的值。输出结果如下:

print in pass , j is 20
print in main , i is 10

可见,pass方法内部对name的值的修改并没有改变实际参数i的值。那么,按照上面的定义,有人得到结论:Java的方法传递是值传递。

但是,很快就有人提出质疑了(哈哈,所以,不要轻易下结论咯。)。然后,他们会搬出以下代码:

public static void main(String[] args) {
    ParamTest pt = new ParamTest();
 
    User hollis = new User();
    hollis.setName("Hollis");
    hollis.setGender("Male");
    pt.pass(hollis);
    System.out.println("print in main , user is " + hollis);
}
 
public void pass(User user) {
    user.setName("hollischuang");
    System.out.println("print in pass , user is " + user);
}

同样是一个pass方法,同样是在pass方法内修改参数的值。输出结果如下:

print in pass , user is User{name='hollischuang', gender='Male'}
print in main , user is User{name='hollischuang', gender='Male'}

经过pass方法执行后,实参的值竟然被改变了,那按照上面的引用传递的定义,实际参数的值被改变了,这不就是引用传递了么。于是,根据上面的两段代码,有人得出一个新的结论:Java的方法中,在传递普通类型的时候是值传递,在传递对象类型的时候是引用传递。

但是,这种表述仍然是错误的。不信你看下面这个参数类型为对象的参数传递:

public static void main(String[] args) {
    ParamTest pt = new ParamTest();
 
    String name = "Hollis";
    pt.pass(name);
    System.out.println("print in main , name is " + name);
}
 
public void pass(String name) {
    name = "hollischuang";
    System.out.println("print in pass , name is " + name);
}

上面的代码输出结果为

print in pass , name is hollischuang
print in main , name is Hollis

这又作何解释呢?同样传递了一个对象,但是原始参数的值并没有被修改,难道传递对象又变成值传递了?

Java中的值传递

上面,我们举了三个例子,表现的结果却不一样,这也是导致很多初学者,甚至很多高级程序员对于Java的传递类型有困惑的原因。

其实,我想告诉大家的是,上面的概念没有错,只是代码的例子有问题。来,我再来给大家画一下概念中的重点,然后再举几个真正恰当的例子。

值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

那么,我来给大家总结一下,值传递和引用传递之前的区别的重点是什么。

img

我们上面看过的几个pass的例子中,都只关注了实际参数内容是否有改变。如传递的是User对象,我们试着改变他的name属性的值,然后检查是否有改变。其实,在实验方法上就错了,当然得到的结论也就有问题了。

为什么说实验方法错了呢?这里我们来举一个形象的例子。再来深入理解一下值传递和引用传递,然后你就知道为啥错了。

你有一把钥匙,当你的朋友想要去你家的时候,如果你直接把你的钥匙给他了,这就是引用传递。这种情况下,如果他对这把钥匙做了什么事情,比如他在钥匙上刻下了自己名字,那么这把钥匙还给你的时候,你自己的钥匙上也会多出他刻的名字。

你有一把钥匙,当你的朋友想要去你家的时候,你复刻了一把新钥匙给他,自己的还在自己手里,这就是值传递。这种情况下,他对这把钥匙做什么都不会影响你手里的这把钥匙。

但是,不管上面哪种情况,你的朋友拿着你给他的钥匙,进到你的家里,把你家的电视砸了。那你说你会不会受到影响?而我们在pass方法中,改变user对象的name属性的值的时候,不就是在“砸电视”么。你改变的不是那把钥匙,而是钥匙打开的房子。

还拿上面的一个例子来举例,我们真正的改变参数,看看会发生什么?

public static void main(String[] args) {
    ParamTest pt = new ParamTest();
 
    User hollis = new User();
    hollis.setName("Hollis");
    hollis.setGender("Male");
    pt.pass(hollis);
    System.out.println("print in main , user is " + hollis);
}
 
public void pass(User user) {
    user = new User();
    user.setName("hollischuang");
    user.setGender("Male");
    System.out.println("print in pass , user is " + user);
}

上面的代码中,我们在pass方法中,改变了user对象,输出结果如下:

print in pass , user is User{name='hollischuang', gender='Male'}
print in main , user is User{name='Hollis', gender='Male'}

我们来画一张图,看一下整个过程中发生了什么,然后我再告诉你,为啥Java中只有值传递。

img

稍微解释下这张图,当我们在main中创建一个User对象的时候,在堆中开辟一块内存,其中保存了name和gender等数据。然后hollis持有该内存的地址0x123456(图1)。

当尝试调用pass方法,并且hollis作为实际参数传递给形式参数user的时候,会把这个地址0x123456交给user,这时,user也指向了这个地址(图2)。

然后在pass方法内对参数进行修改的时候,即user = new User();,会重新开辟一块0X456789的内存,赋值给user。后面对user的任何修改都不会改变内存0X123456的内容(图3)。

上面这种传递是什么传递?肯定不是引用传递,如果是引用传递的话,在执行user = new User();的时候,实际参数的引用也应该改为指向0X456789,但是实际上并没有。

通过概念我们也能知道,这里是把实际参数的引用的地址复制了一份,传递给了形式参数。所以,上面的参数其实是值传递,把实参对象引用的地址当做值传递给了形式参数。

我们再来回顾下之前的那个“砸电视”的例子,看那个例子中的传递过程发生了什么。

img

同样的,在参数传递的过程中,实际参数的地址0X1213456被拷贝给了形参,只是,在这个方法中,并没有对形参本身进行修改,而是修改的形参持有的地址中存储的内容。

**所以,值传递和引用传递的区别并不是传递的内容。而是实参到底有没有被复制一份给形参。**在判断实参内容有没有受影响的时候,要看传的的是什么,如果你传递的是个地址,那么就看这个地址的变化会不会有影响,而不是看地址指向的对象的变化。就像钥匙和房子的关系。

那么,既然这样,为啥上面同样是传递对象,传递的String对象和User对象的表现结果不一样呢?我们在pass方法中使用name = "hollischuang";试着去更改name的值,阴差阳错的直接改变了name的引用的地址。因为这段代码,会new一个String,再把引用交给name,即等价于:

name = new String("hollischuang");

而原来的那个"Hollis"字符串还是由实参持有着的,所以,并没有修改到实际参数的值。

img

所以说,Java中其实还是值传递的,只不过对于对象参数,值的内容是对象的引用。

总结

无论是值传递还是引用传递,其实都是一种求值策略(Evaluation strategy)。在求值策略中,还有一种叫做按共享传递(call by sharing)。其实Java中的参数传递严格意义上说应该是按共享传递。

按共享传递,是指在调用函数时,传递给函数的是实参的地址的拷贝(如果实参在栈中,则直接拷贝该值)。在函数内部对参数进行操作时,需要先拷贝的地址寻找到具体的值,再进行操作。如果该值在栈中,那么因为是直接拷贝的值,所以函数内部对参数进行操作不会对外部变量产生影响。如果原来拷贝的是原值在堆中的地址,那么需要先根据该地址找到堆中对应的位置,再进行操作。因为传递的是地址的拷贝所以函数内对值的操作对外部变量是可见的。

简单点说,Java中的传递,是值传递,而这个值,实际上是对象的引用。

**而按共享传递其实只是按值传递的一个特例罢了。**所以我们可以说Java的传递是按共享传递,或者说Java中的传递是值传递。


ref:

https://segmentfault.com/a/1190000022391398

https://blog.csdn.net/w372426096/article/details/82216742

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java引用详解 的相关文章

  • Segmentation fault错误总结大

    Segmentation Fault原因总结 理解 Segmentation fault https www cnblogs com wpgraceii p 10622582 html
  • OpenCV基础教程大全

    文章目录 关于本教程 OpenCV是什么 xff1f IPPICV 加速 OpenCV有哪些应用 xff1f OpenCV 使用开源许可证 什么是计算机视觉 xff1f 人类的视觉计算机的视觉场景信息可以辅助计算机视觉使用统计的方法来对抗噪
  • 不同编程语言的程序可不可以通过接口相互调用?一些库为啥可以提供不同语言的接口?

    不同编程语言的程序经常互相调用 编程语言之间的直接调用称为互操作 xff0c 他们之间的接口叫做 Foreign Function Interface 在Linux 平台上 xff0c 互操作性最好的语言应该是C xff0c 因为有比较统一
  • 如何使用Markdown内嵌HTML来更改字体颜色

    Markdown 通过简单标记语法 xff0c 使普通文本内容具有一定格式 但它本身不支持修改字体 字号与颜色等功能的 但其支持内嵌HTML xff0c 因此可以实现很多好玩的功能 一 更改字体 大小 颜色 span class token
  • 【程序员读论文】题外篇:怎么读论文

    文章目录 1 如何高效读论文 xff1f 痛苦选择顺序笔记小结讨论 2 如何有针对地高效地阅读一篇学术论文 xff1f 3 一文教你如何快速高效阅读Paper xff08 硕士生版 xff09 前言Paper从哪来Paper怎么读Paper
  • 【程序员读论文】推荐一款OCR软件,识别PDF论文上的文字

    在我们读论文过程中 xff0c 我们会有将PDF论文中的一些文字复制下来的需求 xff0c 但因为PDF的特殊性 xff0c 要么复制不出来 xff0c 要么复制的有问题 通过OCR软件 xff0c 我们可以通过现在的图形文字识别技术 xf
  • uC/OS-III 的特点

    1 其中最有用的功能应该是时间片轮转法 xff08 roundrobin 这个是 uC OS II 中不支持的 xff0c 但是现在已经是 uC OS III 的一个功能了 2 uC OS III 被设计用于 32 位处理器 xff0c 但
  • ORBSLAM2 文章翻译

    ORBSLAM2 一种适用于单目 双目和RGB D相机的开源slam系统 摘要 本文提出了ORB SLAM2 xff0c 一种适用于单目 双目和RGB D相机的slam系统 xff0c 包含地图重用 xff0c 回环检测 xff0c 重定位
  • 【程序员读论文】LeCun, Y., Bengio, Y. & Hinton, G. Deep learning. *Nature* **521,** 436–444 (2015).

    文章目录 一 先看题目 摘要 结论二 文章主体三 总结 今天要读的论文是深度学习的里程碑之作 xff0c 集齐了三位在深度学习领域举足轻重的人物 论文名称 xff1a LeCun Y Bengio Y amp Hinton G Deep l
  • HTML入门教程(非常详细)

    转载于我最喜欢的C语言中文网 xff1a http c biancheng net view 9395 html 文章目录 网站到底是什么 xff1f 1 什么是网页 xff1f 2 什么是网站 xff1f 1 网站服务器 xff08 Se
  • JSON教程(非常详细)

    之前写过有关C语言JSON库 xff1a C语言开源库 在Clion上使用开源库cJSON JSON和XML的对比 xff1a JSON vs XML xff0c 为什么JSON更好 xff1f 下面就好好来了解一下JSON 文章目录 JS
  • 理清gcc、libc、glibc、libc++、libstdc++的关系

    转载一篇好文 xff1a https www jianshu com p a3c983edabd1 当你在Linux下写C C 43 43 代码的时候 xff0c 是不是会遇到许多编译链接的问题 xff1f 时不时报个glibc gcc x
  • Linux中C语言标准库glibc源码下载

    在这篇文章理清gcc libc glibc libc 43 43 libstdc 43 43 的关系 xff0c 我们大概理解了libc xff0c glibc之间的一些关系 下面我们就开了解一些Linux中C语言标准库glibc源码 在这
  • 记录、总结、复盘的重要性和方法(另有周报、月报、年度总结撰写方法)

    文章目录 一 记录1 记录的分类2 学习记录3 工作记录定义分类作用提醒作用跟踪作用证明作用 写好日志时间维度内容维度感想维度 4 生活记录 二 总结和复盘1 总结2 复盘什么叫做复盘 xff1f 什么时候复盘比较合适 xff1f 怎样进行
  • PPT画图文章总结

    一图抵千言 xff0c 在平常的PPT汇报中 xff0c 一张好的图片可以让我们的展示更加清晰 xff0c 也让听得人更快的了解我们的内容 要想起之前师兄发了文章 xff0c 需要提供一个封面示意图 xff0c 当时好像是花钱请别人做的 x
  • 传统学科怎么和深度学习领域结合

    这篇博客 程序员读论文 LeCun Y Bengio Y amp Hinton G Deep learning Nature 521 436 444 2015 中的论文提到深度学习将在很多行业上有广阔的前景 最近看到毕导的公众号发文菜鸡程序
  • 现在快2022年了,c++为什么还要实现(.cpp)和声明(.h)分开?像 Java 或 C# 都不需要声明头文件,C++ 委员会为什么不解决这个问题?

    链接 xff1a https www zhihu com question 506962663 answer 2278836594 因为 C 43 43 牵扯面更广 xff0c 改起来更麻烦 很多语言其实都有一个事实上的实现标准 xff0c
  • Java程序设计基础

    文章目录 Java标识符和关键字标识符关键字 Java注释 xff1a 单行 多行和文档注释1 xff09 单行注释2 xff09 多行注释3 xff09 文档注释 Javadoc xff08 文档注释 xff09 详解Javadoc标签J
  • 几本对于笔试和面试有用的书(干货~)

    黑客帝国 jpg 这儿放几本对程序员笔试和面试有益的书籍o o the power of coding coder jpg 4本408核心书籍 xff1a 数据结构计算机操作系统计算机网络计算机组成原理 面试宝典 xff1a 程序员面试宝典
  • Java类和对象

    文章目录 本章学习要点 Java面向对象 xff1a 对象的概念及面向对象的三个基本特征对象的概念面向对象的三大核心特性继承性封装性多态性 Java认识类和对象Java类的定义及定义类时可用的关键字例 1 Java类的属性 xff1a 成员

随机推荐

  • Java流程控制语句

    文章目录 Java语句 xff1a Java空语句 复合语句和表达式语句语句编写方式空语句表达式语句复合语句例 1 Java if else分支结构精讲if 结构例 1例 2例 3 if else 结构例 4 多条件 if else if
  • Java数组:针对数组(Array)的各种操作

    文章目录 本章学习要点 Java数组简介 xff1a 数组是什么 xff1f Java一维数组的定义 赋值和初始化创建一维数组分配空间例 1 初始化一维数组1 xff09 使用 new 指定数组大小后进行初始化例 22 xff09 使用 n
  • java中类的main方法总结

    一 java中每个类都需要有main方法吗 xff1f 每个类可以有也可以没有main方法 xff0c 甚至所有类里可以都没有main方法 如果你想从某个类做为入口开始运行整个程序 那么就把他设成 public xff0c 之后再里面写个m
  • java中文件名、类名之间的关系

    1 Java保存的文件名必须与类名一致 xff1b 2 如果文件中只有一个类 xff0c 文件名必须与类名一致 xff1b 3 一个Java文件中只能有一个public类 xff1b 4 如果文件中不止一个类 xff0c 文件名必须与pub
  • Java 包(package)详解

    为了更好地组织类 xff0c Java 提供了包机制 xff0c 用于区别类名的命名空间 包的作用 1 把功能相似或相关的类或接口组织在同一个包中 xff0c 方便类的查找和使用 2 如同文件夹一样 xff0c 包也采用了树形目录的存储方式
  • 软件项目开发流程以及人员职责,软件工程中五种常用的软件开发模型整理

    文章目录 一 软件项目开发流程逻辑图开发流程需求分析概要设计详细设计编码测试软件交付验收维护 软件维护软件升级 软件项目开发流程以及人员职责软件工程中五种常用的软件开发模型整理软件系统开发流程七大详细步骤完整介绍 一 软件项目开发流程逻辑图
  • 如何保持专注

    文章目录 部分 1 做一个井井有条的人部分 2 提高专注力部分 3 在集中期间保持动力 专家建议小提示 转载于 xff1a https zh wikihow com E4 BF 9D E6 8C 81 E4 B8 93 E6 B3 A8 不
  • 让开始学java的我困惑的问题解析

    前面已经对java一些基础概念进行了理解 xff1a Java 包 package 详解 java中文件名 类名之间的关系 java中类的main方法总结 文章目录 一个java文件中可以有多个class xff0c 但是只能有一个是pub
  • Jar包详解

    jar包的一些事儿 关于 JAR 包我们应该知道的s
  • astra 深度相机 + orbslam2 ~ 稠密建图

    在ROS下运行ORB SLAM2 主要包括以下几步 xff1a 一 创建ROS工作空间 二 下载usb cam xff08 单目相机驱动包 xff09 三 下载深度相机驱动包 四 下载ORB SLAM2稠密建图代码 五 运行 一 创建ROS
  • Java字符串的处理

    文章目录 本章学习要点 Java定义字符串 xff08 2种方式 xff09 直接定义字符串例 1 使用 String 类定义1 String 2 String String original 3 String char value 4 S
  • Java数字和日期处理:Java数字处理和日期类

    文章目录 本章学习要点 Java Math类的常用方法静态常量例 1 求最大值 最小值和绝对值例 2 求整运算例 3 三角函数运算例 4 指数运算例 5 Java生成随机数 xff08 random 和Random类 xff09 例 1例
  • Java内置的包装类

    文章目录 本章学习要点 Java包装类 装箱和拆箱装箱和拆箱包装类的应用1 实现 int 和 Integer 的相互转换2 将字符串转换为数值类型3 将整数转换为字符串 Java Object类详解toString 方法equals 方法例
  • Java输入/输出(I/O)流

    文章目录 本章学习要点 Java流是什么 xff1f 输入 输出流又是什么 xff1f 什么是输入 输出流输入流输出流 Java系统流例 1 Java字符编码介绍Java File类 xff08 文件操作类 xff09 详解获取文件属性例
  • Java异常处理

    文章目录 本章学习要点 Java异常 xff08 Exception xff09 处理及常见异常异常简介例 1 异常类型 Java中Error和Exception的异同例 1 Java异常处理机制及异常处理的基本结构Java try cat
  • Java注解

    文章目录 本章学习要点 Java注解 xff08 Annotation xff09 简介Java 64 Override注解Java 64 Deprecated注解Java 64 SuppressWarnings xff1a 抑制编译器警告
  • 如何夸人?

    文章目录 夸人要怎么夸到心坎上 xff1f 01 有理有据 xff0c 细节见诚意02 一如既往保持信任与支持03 由表及里 xff0c 夸TA前先夸自己04 先抑后扬 xff0c 对比式夸奖05 创造条件引导TA自夸 如何做一只舔狗 xf
  • Java继承和多态

    文章目录 本章学习要点 Java类的封装例 1 Java封装图书信息类Java继承 xff08 extends xff09 简明教程例 1 单继承继承的优缺点 Java super关键字详解super调用父类构造方法例1例2 super访问
  • java中接口(interface)详解

    分享记录一下java接口的博客 xff1a java中接口 xff08 interface xff09 详解 JAVA基础 接口 xff08 全网最详细教程 xff09
  • java引用详解

    文章目录 一 关于对象与引用之间的一些基本概念 new Vehicle Vehicle veh1二 Java对象及引用三 只有理解了对象和引用的关系 xff0c 才能理解参数传递总结 xff1a 什么是值传递 xff0c 什么是引用传递 为