精华内容
下载资源
问答
  • Java 中引用类型都有哪些

    千次阅读 2019-10-19 22:45:47
    Java 中引用类型都有哪些 Java中对象的引用分为四种级别,这四种级别由高到低依次为:强引用、软引用、弱引用和虚 引用。 强引用( StrongReference) 如果一个对象被被人拥有强引用,那么垃圾回收器绝会回收它。当...

    Java 中引用类型都有哪些

    Java中对象的引用分为四种级别,这四种级别由高到低依次为:强引用、软引用、弱引用和虚 引用。

    强引用( StrongReference)

    如果一个对象被被人拥有强引用,那么垃圾回收器绝会回收它。当内存空间不足, Java 虚拟机宁愿抛出 OutOfMemoryError 错误,使程序异常终止,也不会靠随意
    回收具有强引用的对象来解决内存不足问题。

    Java的对象是位于 heap 中的, heap 中对象有强可及对象、软可及对象、弱可及对象、虚可及对象和不可到
    达对象。应用的强弱顺序是强、软、弱、和虚。对于对象是属于哪种可及的对象,由他的最强的引用决定。如下代
    码:

    
     String abc=new String("abc"); //1
     SoftReference<String> softRef=new SoftReference<String>(abc); //2
     WeakReference<String> wea kRef = new WeakReference<String>(abc); //3
     abc=null; //4
     softRef.clear();//5
    

    第一行在
    heap 堆中创建内容为“ abc ”的对象,并建立 abc 到该对象的强引用,该对象是强可及的。
    第二行和第三行分别建立对
    heap 中对象的软引用和弱引用,此时 heap 中的 abc 对象已经有 3 个引用,显然此
    时 abc 对象仍是强可及的。
    第四行之后
    heap 中对象不再是强可及的,变成软可及的。第五行执行之后变成弱可及的。
    软引用( SoftReferenc)如果一个对象只具有软引用,那么如果内存空间足够,垃圾回收器就不会回收它,如果内存空间不足了,就回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的速缓存。
    软引用可以和一个引用队列(
    ReferenceQueue )联合使用,如果软引用所引用的对象被垃圾回收 Java 虚
    拟机就会把这个软引用加入到与之关联的引用队列中。

    软引用是主要用于内存敏感的高速缓存。jvm 报告内存不足之前会清除所有的软引用,这样以来 gc 就可能收集软可 及的对象,可能解决内存吃紧问题,避免内存溢出。什么时候会被收集取决于 gc 的算法和 gc 运行时可用内存的大小。当 gc 决定要收集软引用时执行以下过程 以上面的 softRef 为例:

    1. 首先将 softRef 的 referent abc )设置为 null ,不再引用 heap 中的 new String(“abc”) 对象。
    2. 将 heap 中的 new String(“abc”) 对象设置为可结束的 (finalizable)
    3. 当 heap 中的 new String(“abc”) 对象的 finalize() 方法被 运行而且该对象占用的内存被释放, softRef被添加到它的 ReferenceQueue.注意 对 ReferenceQueue 软引用和弱引用可以有可无,但是虚引用必须有。

    弱引用与软引用的区别在于 :只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存。不过由于垃圾回收器是一个优先级很低的线程, 因此不一定会很快发现那些只具有弱引用的对象。

    弱引用

    可以和一个引用队列( ReferenceQueue )联合使用,如果弱引用所引用的对象被垃圾回收 Java 虚拟机就会把这个弱引用加入到与之关联的引用队列中。

    虚引用( PhantomReferenc)

    虚引用 顾名思义,就是形同虚设,与其他几种引用都不同,虚引用并不会决定对象的生命周期。如果一个对象仅持有虚引用,那么它就和没有任何引用一样,在任何时候都可能被垃圾回收。虚引用主要用来跟踪对象被垃圾回收的活动。
    虚引用与软引用和弱引用的一个区别在于:
    虚引用必须和引用队列( ReferenceQueue )联合使用 。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中。程序可以通过判断引用队列中是否已经加入了虚引用,来了解被引用的对象是否将要被垃圾回收。程序如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

    展开全文
  • ElasticSearch在Java中引用jar包--pom文件

    万次阅读 2019-04-21 13:26:13
    ElasticSearch在Java中引用jar包--pom文件 适用范围ElasticSearch6.x 如果是ElasticSearch7或以上版本情转到如下链接 REST高级客户端-DocumentApi:https://blog.csdn.net/u014646662/article/details/96473156 ...

    ElasticSearch在Java中引用jar包--pom文件

    适用范围ElasticSearch6.x

    如果是ElasticSearch7或以上版本情转到如下链接

    REST高级客户端-DocumentApi:https://blog.csdn.net/u014646662/article/details/96473156

    REST高级客户端SearchApi:https://blog.csdn.net/u014646662/article/details/96853830

    更多新的查询方式(ElasticSearch相关文档):https://blog.csdn.net/u014646662/article/category/8747782

    对人工智能感兴趣的同学,可以点击以下链接:

    现在人工智能非常火爆,很多朋友都想学,但是一般的教程都是为博硕生准备的,太难看懂了。最近发现了一个非常适合小白入门的教程,不仅通俗易懂而且还很风趣幽默。所以忍不住分享一下给大家。点这里可以跳转到教程。

    https://www.cbedai.net/u014646662

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
      <groupId>GID</groupId>
      <artifactId>ES</artifactId>
      <version>0.0.1-SNAPSHOT</version>
      <name>ES</name>
      
      
    <dependencies>
        <dependency>
          <groupId>org.elasticsearch.client</groupId>
          <artifactId>transport</artifactId>
          <version>6.2.4</version>
        </dependency>    
        
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
          <scope>test</scope>
        </dependency>
      
      </dependencies> 
      
      <build>
          <plugins>
    			<!-- java编译插件 -->
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-compiler-plugin</artifactId>
    				<version>3.2</version>
    				<configuration>
    					<source>1.8</source>
    					<target>1.8</target>
    					<encoding>UTF-8</encoding>
    				</configuration>
    			</plugin>
    		</plugins>
      </build>  
      
    </project>

     

    展开全文
  • java中引用类型的变量和对象的区别

    千次阅读 2017-05-23 09:07:20
    java中引用类型的变量和对象的区别。
    对象:是按照“类”这个模板建立的,建立的位置则是内存
    例如:A是一个类。A a则是创建一个引用变量,a=NEW A()则是在内存中建立一个对象(开辟了1片空间)
    ,对象的模板就是A(可以理解为在空间里复制了A类里的变量到空间里去)。此时就可以使用引用变量a
    去引用对象中的变量了。
    展开全文
  • 但是Java的机制与C++不同,Java中引用也叫句柄,或者说句柄才是其真实名称。类声明的都是一个句柄,调用构造函数才会使得句柄指向类实例。因此Java中没有类似于C++中的复制函数,因为Java的复制都是直接复制句柄...

    综述:    

    在Java中,类实例声明和构造是分开。"T a;"是声明,而"a=new T();"才是构造。引用声明和C++相同。但是Java的机制与C++不同,Java中的引用也叫句柄,或者说句柄才是其真实名称。类声明的都是一个句柄,调用构造函数才会使得句柄指向类实例。因此Java中没有类似于C++中的复制函数,因为Java的复制都是直接复制句柄内容。例如"T b=a;"只不过是将a的句柄复制(赋值)给了b,从而b也指向a指向的类实例。可以看出Java与C++在此处的不同,Java依然只有一个实例,而C++则存在了两个实例。

      所以在函数中,Java的形参都是入参的句柄复制,并且是浅复制(只复制该句柄,而不复制句柄指向的下一层句柄)。因此在函数中,直接修改形参是不能改变入参的。但是如果修改形参指向的对象的下一层句柄则会修改入参。因此在Java中不存在像C/C++中一样的Swap函数。函数的返回值,也是句柄复制。如果在函数中构造一个局部变量类实例,那么是可以返回到外部的,当然那个局部变量的句柄是不存在了。

      Java中要复制对象,需要重载clone函数,并且要分清是浅复制还是深复制(完全构造一个新对象,两者的内部数据和实例不相同)。


    c++ 与java引用具体比较:

    c++中一个引用指向的地址不会改变,改变的是指向地址的内容,然而java中引用指向的地址在变!!
    如果非要对比着看,那么Java中的“引用”倒是和C/C++的指针更像一些,和C++的“引用”很不一样。

    java去除指针概念,就用引用罗...
    你看 java:
    A a = new A(1);
    A b = new A(2);
    b = a;
    没有问题,a 和 b引用同一个对象A(2),原来的A(1)成为没有被引用的对象。 垃圾回收机制会在之后的某个时刻把A(1)干掉。

    而C++则不然。C++的引用就语义上说是“别名”【本质是个const指针,又叫指针常量】,而并不是指针的另一种用法:
    A a = A(1);
    A b = A(2);
    A& c = b; //c 是 b的别名
    c = a; //并不是 c 引用 a,而是拷贝操作 c.operator= ( a )

    就语言机制来说,java的引用是用来管理和命名对象;
    而,C++的引用机制是很纯粹的,就是别名而已。

    每种语言的特性都是整体的有机部分。

    我们知道, java的引用机制是一个很复杂的机制。他必须区分“基本对象”和“复合对象”,你可以想象一下,如果其中没有基本对象,那么我们如何完成对象的复制? 唯一的解决方案是提供两个等于号,或者一律用构造函数.... 但是综合来看,他和垃圾回收形成了相当完美的组合方案。

    而C++ 的引用机制为运算符重载提供了大幅度的支持。C++ 的引用是用类“模拟”基本对象的根本要求。 如果C++使用java那种引用,那么原本漂亮的 operator[]、 proxy class 等就很难实现了。 更进一步, C++ 的运算符重载对 C++ 的模版机制提供了强力的支持

    在c++中,引用只是对于一个变量起的别名,一旦定义就无法修改,即无法再指向其他变量,如程序中,对于a的引用的任何操作都等同于对于a的操作。

    java定义的引用并不是这样。在java中,引用相当与指针,它与c中的指针主要有两个区别:一是引用不能进行地址操作,如数组的加一 操作,相当于引用只是只是指向数据的一个副本,而不是数据本身,这样就避免了由于对于地址的误操作而改变其他变量的值,甚至危害到系统的安全。二是 java中的引用只能指向对象,他的引用是在实例化对象时系统直接生成的,因此对于普通数据类型是不能进行引用定义的,如果要对普通数据类型进行函数调用 时的地址传递(即java中的引用传递),必须把数据封装到类中。
    java的这种特性使得在java的函数或类的参数传递时可以实现与c中指针相同的功能。


    具体应用:

    指针和引用在C++中很常用,但是对于它们之间的区别很多初学者都不是太熟悉,下面来谈谈他们2者之间的区别和用法。

    1.指针和引用的定义和性质区别:

    (1)指针:指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元;而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已。如:

    int a=1;int *p=&a;

    int a=1;int &b=a;

    上面定义了一个整形变量和一个指针变量p,该指针变量指向a的存储单元,即p的值是a存储单元的地址。

    而下面2句定义了一个整形变量a和这个整形a的引用b,事实上a和b是同一个东西,在内存占有同一个存储单元。

    (2)可以有const指针,但是没有const引用;

    (3)指针可以有多级,但是引用只能是一级(int **p;合法 而 int &&a是不合法的)

    (4)指针的值可以为空,但是引用的值不能为NULL,并且引用在定义的时候必须初始化;

    (5)指针的值在初始化后可以改变,即指向其它的存储单元,而引用在进行初始化后就不会再改变了。

    (6)"sizeof引用"得到的是所指向的变量(对象)的大小,而"sizeof指针"得到的是指针本身的大小;

    (7)指针和引用的自增(++)运算意义不一样;

    2.指针和引用作为函数参数进行传递时的区别。

    (1)指针作为参数进行传递:

    复制代码
    #include<iostream>
    using namespace std;
    
    void swap(int *a,int *b)
    {
      int temp=*a;
      *a=*b;
      *b=temp;
    }
    
    int main(void)
    {
      int a=1,b=2;
      swap(&a,&b);
      cout<<a<<" "<<b<<endl;
      system("pause");
      return 0;
    }
    复制代码

    结果为2 1;

    用指针传递参数,可以实现对实参进行改变的目的,是因为传递过来的是实参的地址,因此使用*a实际上是取存储实参的内存单元里的数据,即是对实参进行改变,因此可以达到目的。

    再看一个程序;

    复制代码
    #include<iostream>
    using namespace std;
    
    void test(int *p)
    {
      int a=1;
      p=&a;
      cout<<p<<" "<<*p<<endl;
    }
    
    int main(void)
    {
        int *p=NULL;
        test(p);
        if(p==NULL)
        cout<<"指针p为NULL"<<endl;
        system("pause");
        return 0;
    }
    复制代码

    运行结果为:

    0x22ff44 1

    指针p为NULL

    大家可能会感到奇怪,怎么回事,不是传递的是地址么,怎么p回事NULL?事实上,在main函数中声明了一个指针p,并赋值为NULL,当调用test函数时,事实上传递的也是地址,只不过传递的是指地址。也就是说将指针作为参数进行传递时,事实上也是值传递,只不过传递的是地址。当把指针作为参数进行传递时,也是将实参的一个拷贝传递给形参,即上面程序main函数中的p何test函数中使用的p不是同一个变量,存储2个变量p的单元也不相同(只是2个p指向同一个存储单元),那么在test函数中对p进行修改,并不会影响到main函数中的p的值。

    如果要想达到也同时修改的目的的话,就得使用引用了。

    2.将引用作为函数的参数进行传递。

    在讲引用作为函数参数进行传递时,实质上传递的是实参本身,即传递进来的不是实参的一个拷贝,因此对形参的修改其实是对实参的修改,所以在用引用进行参数传递时,不仅节约时间,而且可以节约空间。

    看下面这个程序:

    复制代码
    #include<iostream>
    using namespace std;
    
    void test(int &a)
    {
      cout<<&a<<" "<<a<<endl;
    }
    
    int main(void)
    {
        int a=1;
        cout<<&a<<" "<<a<<endl;
        test(a);
        system("pause");
        return 0;
    }
    复制代码

    输出结果为: 0x22ff44 1

              0x22ff44 1

    再看下这个程序:

    这足以说明用引用进行参数传递时,事实上传递的是实参本身,而不是拷贝。

    所以在上述要达到同时修改指针的目的的话,就得使用引用了。

    复制代码
    #include<iostream>
    using namespace std;
    
    void test(int *&p)
    {
      int a=1;
      p=&a;
      cout<<p<<" "<<*p<<endl;
    }
    
    int main(void)
    {
        int *p=NULL;
        test(p);
        if(p!=NULL)
        cout<<"指针p不为NULL"<<endl;
        system("pause");
        return 0;
    }
    复制代码

    输出结果为:0x22ff44 1

             指针p不为NULL


    C++ 引用的本质?深入分析C++引用:

    引言

          我选择写 C++ 中的引用是因为我感觉大多数人误解了引用。而我之所以有这个感受是因为我主持过很多 C++ 的面试,并且我很少从面试者中得到关于 C++ 引用的正确答案。

           那么 c++ 中引用到底意味这什么呢?通常一个引用让人想到是一个引用的变量的别名,而我讨厌将 c++ 中引用定义为变量的别名。这篇文章中,我将尽量解释清楚, c++ 中根本就没有什么叫做别名的东东。


    背景

    在 c/c++ 中,访问一个变量只能通过两种方式被访问,传递,或者查询。这两种方式是:

    1. 通过值 访问 / 传递变量

    2. 通过地址 访问 / 传递变量 – 这种方法就是指针

           除此之外没有第三种访问和传递变量值的方法。引用变量也就是个指针变量,它也拥有内存空间。最关键的是引用是一种会被编译器自动解引用的指针。很难相信么?让我们来看看吧。。。

    下面是一段使用引用的简单 c++ 代码

    1. #include <iostream.h>  
    2. int main()  
    3. {  
    4.     int i = 10;   // A simple integer variable  
    5.     int &j = i;   // A Reference to the variable i  
    6.     j++;   // Incrementing j will increment both i and j.  
    7.     // check by printing values of i and j  
    8.     cout<<  i  <<  j  <<endl; // should print 11 11  
    9.     // Now try to print the address of both variables i and j  
    10.     cout<<  &i  <<  &j  <<endl;  
    11.     // surprisingly both print the same address and make us feel that they are  
    12.     // alias to the same memory location.  
    13.     // In example below we will see what is the reality  
    14.     return 0;  
    15. }   

     

    引用其实就是 c++ 中的指针常量。表达式   int &i = j; 将会被编译器转化成 int *const i = &j; 而引用之所以要初始化是因为 const 类型变量必须初始化,这个指针也必须有所指。下面我们再次聚焦到上面这段代码,并使用编译器的那套语法将引用替换掉。

    1. #include <iostream.h>  
    2. int main()  
    3. {  
    4.     int i = 10;            // A simple integer variable  
    5.     int *const j = &i;     // A Reference to the variable i  
    6.     (*j)++;                // Incrementing j. Since reference variables are   
    7.                           // automatically dereferenced by compiler  
    8.     // check by printing values of i and j  
    9.     cout<<  i  <<  *j  <<endl; // should print 11 11  
    10.     // A * is appended before j because it used to be reference variable  
    11.     // and it should get automatically dereferenced.  
    12.     return 0;  
    13. }  


        读者一定很奇怪为什么我上面这段代码会跳过打印地址这步。这里需要一些解释。因为引用变量时(使用变量时)会被编译器自动解引用的,那么一个诸如   cout << &j << endl; 的语句,编译器就会将其转化成语句   cout << &*j << endl;   现在 &* 会相互抵消,这句话变的毫无意义,而 cout 打印的 j 值就是 i 的地址,因为其定义语句为 int *const j = &i;

          所以语句 cout << &i << &j << endl; 变成了 cout << &i << &*j << endl; 这两种情况都是打印输出 i 的地址。这就是当我们打印普通变量和引用变量的时候会输出相同地址的原因。


    下面给出一段复杂一些的代码,来看看引用在级联 (cascading) 中是如何运作的。

    1. #include <iostream.h>  
    2. int main()  
    3. {  
    4.     int i = 10; // A Simple Integer variable  
    5.     int &j = i; // A Reference to the variable  
    6.     // Now we can also create a reference to reference variable.   
    7.     int &k = j; // A reference to a reference variable  
    8.     // Similarly we can also create another reference to the reference variable k  
    9.     int &l = k; // A reference to a reference to a reference variable.  
    10.     // Now if we increment any one of them the effect will be visible on all the  
    11.     // variables.  
    12.     // First print original values  
    13.     // The print should be 10,10,10,10  
    14.     cout<<  i  <<  ","  <<  j  <<  ","  <<  k  <<  ","  <<  l  <<endl;  
    15.     // increment variable j  
    16.     j++;   
    17.     // The print should be 11,11,11,11  
    18.     cout<<  i  <<  ","  <<  j  <<  ","  <<  k  <<  ","  <<  l  <<endl;  
    19.     // increment variable k  
    20.     k++;  
    21.     // The print should be 12,12,12,12  
    22.     cout<<  i  <<  ","  <<  j  <<  ","  <<  k  <<  ","  <<  l  <<endl;  
    23.     // increment variable l  
    24.     l++;  
    25.     // The print should be 13,13,13,13  
    26.     cout<<  i  <<  ","  <<  j  <<  ","  <<  k  <<  ","  <<  l  <<endl;  
    27.     return 0;  
    28. }  

     

    下面这段代码是将上面代码中的引用替换之后代码,也就是说明我们不依赖编译器的自动替换功能,手动进行替换也能达到相同的目标。

    1. #include <iostream.h>  
    2. int main()  
    3. {  
    4.     int i = 10;         // A Simple Integer variable  
    5.     int *const j = &i;     // A Reference to the variable  
    6.     // The variable j will hold the address of i  
    7.     // Now we can also create a reference to reference variable.   
    8.     int *const k = &*j;     // A reference to a reference variable  
    9.     // The variable k will also hold the address of i because j   
    10.     // is a reference variable and   
    11.     // it gets auto dereferenced. After & and * cancels each other   
    12.     // k will hold the value of  
    13.     // j which it nothing but address of i  
    14.     // Similarly we can also create another reference to the reference variable k  
    15.     int *const l = &*k;     // A reference to a reference to a reference variable.  
    16.     // The variable l will also hold address of i because k holds address of i after  
    17.     // & and * cancels each other.  
    18.     // so we have seen that all the reference variable will actually holds the same  
    19.     // variable address.  
    20.     // Now if we increment any one of them the effect will be visible on all the  
    21.     // variables.  
    22.     // First print original values. The reference variables will have * prefixed because   
    23.     // these variables gets automatically dereferenced.  
    24.     // The print should be 10,10,10,10  
    25.     cout<<  i  <<  ","  <<  *j  <<  ","  <<  *k  <<  ","  <<  *l  <<endl;  
    26.     // increment variable j  
    27.     (*j)++;   
    28.     // The print should be 11,11,11,11  
    29.     cout<<  i  <<  ","  <<  *j  <<  ","  <<  *k  <<  ","  <<  *l  <<endl;  
    30.     // increment variable k  
    31.     (*k)++;  
    32.     // The print should be 12,12,12,12  
    33.     cout<<  i  <<  ","  <<  *j  <<  ","  <<  *k  <<  ","  <<  *l  <<endl;  
    34.     // increment variable l  
    35.     (*l)++;  
    36.     // The print should be 13,13,13,13  
    37.     cout  <<  i  <<  ","  <<  *j  <<  ","  <<  *k  <<  ","  <<  *l  <<endl;  
    38.     return 0;  
    39. }  

            

     我们通过下面代码可以证明 c++ 的引用不是神马别名,它也会占用内存空间的。

    1. #include <iostream.h>  
    2. class Test  
    3. {  
    4.     int &i;   // int *const i;  
    5.     int &j;   // int *const j;  
    6.     int &k;   // int *const k;   
    7. };  
    8. int main()  
    9. {      
    10.     // This will print 12 i.e. size of 3 pointers  
    11.     cout<<  "size of class Test = "  <<   sizeof(class Test)  <<endl;  
    12.     return 0;  
    13. }  

    结论

    我希望这篇文章能把 c++ 引用的所有东东都解释清楚,然而我要指出的是 c++ 标准并没有解释编译器如何实现引用的行为。所以实现取决于编译器,而大多数情况下就是将其实现为一个 const 指针。


    引用支持 c++ 虚函数机制的代码

    1. #include <iostream.h>  
    2. class A  
    3. {  
    4. public:  
    5.          virtual void print() { cout<<"A.."<<endl; }  
    6. };  
    7. class B : public A  
    8. {  
    9. public:  
    10.          virtual void print() { cout<<"B.."<<endl; }  
    11. };  
    12.    
    13. class C : public B  
    14. {  
    15. public:  
    16.          virtual void print() { cout<<"C.."<<endl; }  
    17. };  
    18. int main()  
    19. {  
    20.          C c1;  
    21.          A &a1 = c1;  
    22.          a1.print(); // prints C  
    23.          A a2 = c1;  
    24.          a2.print(); // prints A  
    25.          return 0;  
    26. }  

    上述代码使用引用支持虚函数机制。如果引用仅仅是一个别名,那如何实现虚函数机制,而虚函数机制所需要的动态信息只能通过指针才能实现,所以更加说明引用其实就是一个 const 指针。


    补充:const 指针(指针常量)与指向const的指针(常量指针)

        当使用带有const的指针时其实有两种意思。一种指的是你不能修改指针本身的内容,另一种指的是你不能修改指针指向的内容。听起来有点混淆一会放个例子上来就明白了。
        先说指向const的指针,它的意思是指针指向的内容是不能被修改的。它有两种写法。
          const int* p; (推荐)
          int const* p;
          第一种可以理解为,p是一个指针,它指向的内容是const int 类型。p本身不用初始化它可以指向任何标示符,但它指向的内容是不能被改变的。
          第二种很容易被理解成是p是一个指向int的const指针(指针本身不能被修改),但这样理解是错误的,它也是表示的是指向const的指针(指针指向的内容是不能被修改的),它跟第一种表达的是一个意思。为了避免混淆推荐大家用第一种。
          再说const指针,它的意思是指针本身的值是不能被修改的。它只有一种写法
          int* const p=一个地址; (因为指针本身的值是不能被修改的所以它必须被初始化)
          这种形式可以被理解为,p是一个指针,这个指针是指向int 的const指针。它指向的值是可以被改变的如*p=3;
          还有一种情况是这个指针本身和它指向的内容都是不能被改变的,请往下看。
          const int* const p=一个地址;
          int const* const p=一个地址;
          看了上面的内容是不是有点晕,没关系,你不用去背它,用的多了就知道了,还有个技巧,通过上面的观察我们不难总结出一点规律,是什么呢?也许你已经看出来了,什么!竟然没看也来,那只好还得听我唠叨了。这个规律就是: 指向const的指针(指针指向的内容不能被修改)const关健字总是出现在*的左边而const指针(指针本身不能被修改)const关健字总是出现在*的右边,那不用说两个const中间加个*肯定是指针本身和它指向的内容都是不能被改变的。有了这个规则是不是就好记多了。
          什么还是晕,那就看下面的程序,你把它编译一下看看错误提示就明白了。

    复制代码
     1 #include <iostream>
     2 
     3 using namespace std;
     4 
     5 int main(int argc, char *argv[])
     6 {
     7     int a=3;
     8     int b;
     9     
    10     /*定义指向const的指针(指针指向的内容不能被修改)*/ 
    11     const int* p1; 
    12     int const* p2; 
    13     
    14     /*定义const指针(由于指针本身的值不能改变所以必须得初始化)*/ 
    15     int* const p3=&a; 
    16     
    17     /*指针本身和它指向的内容都是不能被改变的所以也得初始化*/
    18     const int* const p4=&a;
    19     int const* const p5=&b; 
    20     
    21      p1=p2=&a; //正确
    22      *p1=*p2=8//不正确(指针指向的内容不能被修改)
    23     
    24      *p3=5//正确
    25      p3=p1; //不正确(指针本身的值不能改变) 
    26     
    27      p4=p5;//不正确 (指针本身和它指向的内容都是不能被改变) 
    28      *p4=*p5=4//不正确(指针本身和它指向的内容都是不能被改变) 
    29      
    30     return 0
    31 }
    复制代码

    展开全文
  • java中引用类型的数据,传递的是内存地址,像类,数组,接口,String等等都是引用类型!看下面的代码和截图!public class Test2 { // java中引用类型的数据传递的是内存地址 private Map&lt;String, Student&...
  • java中引用和指针

    千次阅读 2019-01-07 16:53:42
    首先,提个问题:JAVA中没有指针,JAVA中有指针,哪个一个对呢? 答:都对,JAVA中没有指针,因为我们不能对指针直接操作,像C++那样用-&gt;来访问变量。 JAVA有指针,因为JDK中封装了指针。(现在我们就来找到...
  • Java中 引用类型初始化后未赋值之前的值为null 基本数据类型 byte short int long boolean char float double import java.util.Arrays; public class Test { public static byte byte1; public static short s; ...
  • java中引用kotlin中的全局变量

    千次阅读 2018-02-06 15:11:01
    如果要在java代码中引用这个变量直接写id是肯定会有问题的 public void main(String[] args){ System.out.print(id); } 这里会提示你引用了 xx的私有成员 kotlin会给所有的变量提供默认的 get() 方法 所以...
  • java中引用数据类型有哪些?

    万次阅读 多人点赞 2016-07-18 09:45:37
    Java中有俩种数据类型,其中主要有8中基本数据类型和引用数据类型,除了8中基本数据类型以外都是引用数据类型,8中基本数据类型分别是byte,short,int,long,char,boolean,float,double,具体如下:1、boolean:数据值...
  • Java中引用变量与对象

    千次阅读 2017-05-16 16:41:32
    Java中引用变量相当于C语言中的指针,它的作用是指向某个对象.比如 Child t;(引用变量的申明并创建了一个引用空间) t=new Child();(创建了一个Child对象,并 把这个对象在堆内存中的地址赋给t) t 是 一个...
  • Java中引用传值问题

    千次阅读 2018-06-26 14:34:57
    今天花了一整天去实现一个项目功能,果然只搞理论是不行的,距离上一次写项目已经快有半年了,今天无论是效率还是熟练度都大不如前,》》》好了言归正传,今天要说的这个问题其实很简单——在方法的参数传递问题。...
  • java中引用变量

    千次阅读 2012-06-21 14:08:01
    String s = new String("abc");创建了几个String Object? 引用变量与对象的区别;... 一、引用变量与对象:除了一些早期的Java书籍和现在的垃圾书籍,人们都可以从中比较清楚地学习到两者的区别。
  • Java中引用类型的参数也是值传递

    千次阅读 2019-03-14 20:28:13
    Java引用类型作为参数传递给方法的时候,发生的仅仅是将引用类型变量的值复制一份给方法,让方法的参数变量也指向内存的对象区域。
  • 关于JAVA中引用及返回值的问题

    千次阅读 2017-11-11 14:35:51
    在《java编程思想》有这样一段描述:“每种编程语言都有自己的数据处理方式。有些时候,程序员必须注意将要处理的数据是什么类型。你是直接操纵元素,还是用某种基于特殊语法的间接表示(例如C/C++里的指针)来...
  • JAVA中引用本身占用内存空间的问题

    千次阅读 2018-05-28 09:47:18
    Java中,一个空Object对象的大小是8byte,这个大小只是保存堆中一个没有任何属性的对象的大小。看下面语句:Java代码 Object ob = new Object();这样在程序中完成了一个Java对象的生命,但是它所占的空间为:4...
  • Java中引用与指针的区别

    千次阅读 2018-07-07 12:46:19
    (7)作为参数:Java的方法参数只是传值,引用作为参数使用时,会给函数内引用的值的COPY,所以在函数内交换俩个引用参数是没意义的,因为函数只交换参数的COPY值,但在函数内改变一个引用参数的属性是有意义的,...
  • 解决 java 中引用的jar包乱码问题

    千次阅读 2018-07-18 11:40:16
    修改Eclipse中文本文件的默认编码:windows-&gt;... 修改JAVA源文件的默认编码:windows-&gt;Preferences-&gt;general-&gt;Content Types-&gt;右侧Context Types树,点开Tex...
  • 例如: Dog a=new Dog(); 引用变量a的作用是获得new Dog()所创建对象的位置或者说是地址吗
  • java中引用类型和基本类型区别

    千次阅读 2018-12-03 20:06:58
    参考:https://www.cnblogs.com/bekeyuan123/p/7468845.html https://blog.csdn.net/ldsh304/article/details/75332016
  • Java中引用String 转换为char数组

    千次阅读 2016-10-16 22:42:36
    /*作者:陈天祥 时间:2016.10.10 ...功能:引用String 转换为char数组*/ public class Text_1 { public static void main(String[] args) { // TODO Auto-generated method stub String classone="I L
  • 之前听说说成员的基本类型是在堆分配空间,而如果是在函数,那么就是在栈的局部变量表分配空间,是这样吗?那么引用类型呢?和基本类型一样吗?
  • 转载地址:https://blog.csdn.net/lzwglory/article/details/18263245 将文件放入项目根目录就可以了
  • 一.Java中什么叫做引用类型变量? 引用:就是按内存地址查询  比如:String s = new String();这个其实是在栈内存里分配一块内存空间为s,在堆内存里 new了一个String类型的空间,在运行时是 栈内存里的...
  • Java中引用类型和原始类型的区分

    千次阅读 2011-07-31 12:26:50
    Java 提供两种不同的类型:引用类型和原始类型(或内置类型)。另外, Java还为每个原始类型提供了封装类(Wrapper)。如果需要一个整型变量,是使用基本的int 型呢,还是使用 Integer 类的一个对象呢?如果需要声明...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 86,807
精华内容 34,722
关键字:

java中引用

java 订阅