精华内容
下载资源
问答
  • 引用的特点

    2015-10-20 11:23:00
    引用的语言层特点  引用的作用是为变量起一个别名。 int a; int &b = a; int 牛二; int & 二蛋 = 牛二;  上例中,定义了一个变量a,而b是a的别名。牛阿姨生了一个Baby叫牛二,牛二有个小名...

    引用的语言层特点

      引用的作用是为变量起一个别名。

    int a;
    int &b = a;
    
    int 牛二;
    int & 二蛋 = 牛二;

      上例中,定义了一个变量a,而b是a的别名。牛阿姨生了一个Baby叫牛二,牛二有个小名叫二蛋。张大爷叫二蛋的时候,牛二知道叫的就是他。类似的,程序员在读写b的时候,也就是再读写a。

     

    引用的主要用途

    1. 在于函数调用时,能通过修改形参的值而改变对应实参的值。
    2. 使用引用编程,程序员编程更加直观。

    example 1:

    #include <iostream>
    using namespace std;
    
    void swap(int a ,int b)
    {
      int tmp;
      tmp = a;
      a= b;
      b = tmp;  
    }
    
    void main()
    {
      int i = 1, j =2;
      ......
      swap(i,j);
      ......
    }

      虽然编程看着挺直观,但是不能交换i,j的值,因为形参和实参是不同的内存单元。

    example 2:

    #include <iostream>
    using namespace std;
    
    void swap(int *a ,int *b)
    {
      int tmp;
      tmp = *a;
      *a= *b;
      *b = tmp;  
    }
    
    void main()
    {
      int i = 1, j =2;
      ......
      swap(i,j);
      ......
    }

      用指针肯定能交换i,j的值,通过形参中的地址可以访问到原始的实参变量,可以修改实参的内容。但是,这种方式,编程不直观,总是要在变量前边加一个"*"号。

    example 3:

    #include <iostream>
    using namespace std;
    
    void swap(int &a ,int &b)
    {
      int tmp;
      tmp = a;
      a= b;
      b = tmp;  
    }
    
    void main()
    {
      int i = 1, j =2;
      ......
      swap(i,j);
      ......
    }

      使用引用方式,既可以从形参那里修改实参的值,同时编程直观。

    小结

      引用规避了直接传递和指针传递两种方式的缺点,而集中它们的优点,衍生出来的一种更优秀的传递方式。

     

    ==============================================================

    引用的实现机制上

      引用的实现机制上,是一个“常量指针”。在最开始的例程中,定义了一个引用型变量b,编译器会将其按照指针的操作方式,将a的地址赋给b。

      引用用在函数调用上,本质上与指针传递参数没有差别。只不过指针传递参数有两个缺点,其一是操作不直观;其二指针指向可能会被修改,这样的编程不安全。而引用相当于是对指针传递参数这种方式进行了封装,规避了这两种缺点。对于程序员编程来说,他不再为指针传递参数的缺点而苦恼,因为编译器已经帮助他完成了这部分工作,而事实上他进行的操作就是指针传递参数。

     

      引用和指针传递参数无论是在效率上还是在空间上都是完全一样的,如果妄想不传入地址就修改实参的值,简直就是天方夜谭,这就说明引用的本质就是指针。毕竟它们的行为都太相似了,如果不是这样,你还有什么方法去实现引用吗?记住,引用只不过是编译器为你提供的一个有用且安全的工具,对于机器代码可无法表示它,它把指针一对多的缺点去除,禁止了你的不安全的操作。但回到问题的本源,他们没有任何区别。

                                    摘自:引用的本质是什么?

     

    参考博客:

      引用的本质是什么?
          从底层汇编理解 c++ 引用实现机制

    转载于:https://www.cnblogs.com/amanlikethis/p/4894276.html

    展开全文
  • Java中的引用按强度可依次分为:强引用,软引用,弱引用和虚引用。...强引用的特点: 只要某个对象与强引用有关联,那么这个对象就永远不会被回收。即使内存不足,JVM宁愿抛出OOM(内存溢出)异常,也不会去回

    Java中的引用按强度可依次分为:强引用,软引用,弱引用和虚引用。
    在这里插入图片描述
    如上图,除了强引用FinalReference外,其他三种引用类型均为public,可以在应用程序中直接使用。

    强引用

    强引用在代码之中是普遍存在的,我们写的代码绝大部分都是强引用。比如:

    Object o = new Object();
    String s = new String("hello");
    

    强引用的特点:
    只要某个对象与强引用有关联,那么这个对象就永远不会被回收。即使内存不足,JVM宁愿抛出OOM(内存溢出)异常,也不会去回收它。

    但是强引用的这种特点会导致出现内存泄漏的问题,所以我们可以手动切断这些对象与强引用之间的关联,让JVM可以去回收它。如:

    o = null;
    s = null;
    

    软引用

    软引用就是使用关键字SoftReference将对象包裹起来:

    SoftReference<String> stringSoftReference = new SoftReference<>(new String("hello"));
    

    获取被包裹的对象也非常简单,只需要调用SoftReference对象的get方法就可以了:

    String s = stringSoftReference.get();
    System.out.println(s);
    //打印结果:hello
    

    软引用的特点:
    当内存不足时会触发GC,然后如果GC之后内存还是不足,才会把软引用包裹的对象给干掉。也就是说,只有在内存不足的时候,JVM才会回收该对象。

    比如我们可以做个实验,先将ide中堆的大小设为设为2M,然后运行下面的程序:

    import java.lang.ref.SoftReference;
    
    public class Test {
        public static void main(String[] args) {
            SoftReference<byte[]> softReference = new SoftReference<>(new byte[1024*1024]);
            if(softReference.get() != null) {
                System.out.println("对象没有被回收");
            }else {
                System.out.println("对象被回收了");
            }
            //看看gc之后对象有没有被回收
            System.gc();
            if(softReference.get() != null) {
                System.out.println("对象没有被回收");
            }else {
                System.out.println("对象被回收了");
            }
            //再创建一个大小为1M的数组让堆的内存不足,看看对象会不会被回收
            byte[] bytes = new byte[1024*1024];
            if(softReference.get() != null) {
                System.out.println("对象没有被回收");
            }else {
                System.out.println("对象被回收了");
            }
        }
    }
    //运行结果:
    对象没有被回收
    对象没有被回收
    对象被回收了
    

    软引用的作用就是: 它比较适合用作缓存,当内存足够的时候,可以正常的拿到缓存。当内存不足的时候就会先干掉这些缓存,然后不至于马上抛出OOM。

    弱引用

    弱引用就是使用WeakReference将对象包裹起来:

     WeakReference<byte[]> weakReference = new WeakReference<>(new byte[10]);
    

    获取被包裹的对象同样只需要调用WeakReference对象的get方法就可以了:

    byte[] bytes = weakReference.get();
    

    弱引用的特点:

    不管内存是否足够,只要发生GC,都会被回收。

    import java.lang.ref.WeakReference;
    
    public class Test {
        public static void main(String[] args) {
            WeakReference<byte[]> weakReference = new WeakReference<>(new byte[10]);
            System.out.println(weakReference.get());
            System.gc();
            System.out.println(weakReference.get());
        }
    }
    //运行结果:
    [B@1540e19d
    null
    

    可以看到明明内存很充足,但是在gc之后,对象还是被回收了。

    弱引用的用途: 最常见的用处就是在哈希表中。因为哈希表中任何Java对象都可以作为键来使用。当一个键值对被放入到哈希表中之后,哈希表对象本身就有了对这些键和值对象的引用。如果这种引用是强引用的话,那么只要哈希表对象本身还存活,其中所包含的键和值对象是不会被回收的。如果某个存活时间很长的哈希表中包含的键值对很多,最终就有可能消耗掉JVM中全部的内存。所以对于这种情况的解决办法就是使用弱引用来引用这些对象,这样哈希表中的键和值对象都能被垃圾回收。Java中有一个WeakHashMap就是这个作用。

    虚引用

    也称为幽灵引用或者幻影引用,它是最弱的一种引用关系。一个对象是否有虚引用的存在,完全不会对其生存时间构成影响。

    它跟软引用和弱引用有点不同,除了要使用关键字PhantomReference将对象包裹起来外,还需要搭配ReferenceQueue来使用:

    ReferenceQueue<Object> queue = new ReferenceQueue<>();
    //将ReferenceQueue对象作为第二个参数传进去
    PhantomReference<byte[]> phantomReference = new PhantomReference<>(new byte[10],queue);
    

    获取被包裹的对象同样也是调用get方法:

     System.out.println(phantomReference.get());
     //运行结果:
     null
    

    可以看到明明内存充足,而且也没有发生gc,为什么打印结果为null呢?点开其get方法源码可以看到:

    public T get() {
        return null;
    }
    

    可以看到只要调用了get方法,返回值均为null。为什么呢?

    虚引用特点:
    无法通过虚引用来获取对一个对象的真实引用。

    前面提到了它必须配合ReferenceQueue一起使用。因为在GC准备回收一个对象时,如果发现它还有虚引用,就会在GC时,把这个虚引用加入到与之关联的ReferenceQueue队列中。好处就是如果发现某个虚引用已经被加入到引用队列,那么就可以在所引用的对象的内存被回收之前采取必要的行动。

    虚引用用途: 可以用来跟踪对象被GC的活动,当一个虚引用关联的对象被垃圾收集器回收之前会收到一条系统通知,然后可以选择采取一些行动。

    展开全文
  • c++引用的特点

    千次阅读 2020-08-24 01:26:41
    (3)使用指针作为函数的参数虽然也能达到使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用”*指针变量名”的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数...

     1.将“引用”作为函数参数有哪些特点?
       (1)传递引用给函数与传递指针的效果是一样的。
       (2)使用引用传递函数的参数,在内存中并没有产生是实参的副本,它是直接对实参操作
       (3)使用指针作为函数的参数虽然也能达到使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用”*指针变量名”的形式进行运算,这很容易产生错误且程序的阅读性较差;另一方面,在主调函数的调用点处,必须用变量的地址作为实参。而引用更容易使用,更清晰。

    2.将“引用”作为函数返回值类型的格式、好处和需要遵守的规则?
       好处:在内存中不产生被返回值的副本
     注意:
       1.不能返回局部变量的引用,主要是局部变量会在函数返回后被销毁,因此被返回的引用就成了无所指的引用,程序会进入未知状态
       2.不能返回函数内部new分配的内存的引用(容易造成内存泄漏)
       3.可以返回类成员的引用,但最好是const

    展开全文
  • Java 8新特性方法引用对于引用来说我们一般都是用在对象,而对象引用的特点是:不同的引用对象可以操作同一块内容!Java 8的方法引用定义了四种格式:引用静态方法 ClassName :: staticMethodName引用对象方法: ...

    Java 8新特性方法引用

    对于引用来说我们一般都是用在对象,而对象引用的特点是:不同的引用对象可以操作同一块内容!

    Java 8的方法引用定义了四种格式:

    引用静态方法     ClassName :: staticMethodName

    引用对象方法:  Object:: methodName

    引用特定类型方法: ClassName :: methodName

    引用构造方法: ClassName  :: new

    静态方法引用示例

    /**

    * 静态方法引用

    * @param

    引用方法的参数类型

    * @param 引用方法的返回类型

    */

    @FunctionalInterface

    interface FunStaticRef

    {

    public R tranTest(P p);

    }

    public static void main(String[] args) {

    /*

    * 静态方法引用: public static String valueOf

    * 即将String的valueOf() 方法引用为 FunStaticRef#tranTest 方法

    */

    FunStaticRef funStaticRef = String::valueOf;

    String str = funStaticRef.tranTest(10000);

    System.out.println(str.replaceAll("0", "9"));

    }

    对象方法引用示例

    /**

    * 普通方法引用

    * @param 引用方法返回类型

    */

    @FunctionalInterface

    interface InstanRef{

    public R upperCase();

    }

    public static void main(String[] args) {

    /*

    * 普通方法的引用: public String toUpperCase()

    *

    */

    String str2 = "i see you";

    InstanRef instanRef = str2 :: toUpperCase;

    System.out.println(instanRef.upperCase());

    }

    特定类型方法引用示例

    特定方法的引用较为难理解,本身其引用的是普通方法,但是引用的方式却为: ClassName :: methodName

    /**

    * 特定方法的引用

    * @param

    */

    @FunctionalInterface

    interface SpecificMethodRef

    {

    public int compare(P p1 , P p2);

    }

    public static void main(String[] args) {

    /*

    * 特定方法的引用 public int compareTo(String anotherString)

    * 与之前相比,方法引用前不再需要定义对象,而是可以理解为将对象定义在了参数上!

    */

    SpecificMethodRef specificMethodRef = String :: compareTo;

    System.out.println(specificMethodRef.compare("A","B"));

    ConstructorRef constructorRef = Book :: new;

    Book book = constructorRef.createObject("Java",100.25);

    System.out.println(book);

    }

    构造方法引用示例

    class Book{

    private String title;

    private double price;

    public Book() {

    }

    public Book(String title,double price){

    this.price = price;

    this.title = title;

    }

    @Override

    public String toString() {

    return "Book{" +"title='" + title + ''' +", price=" + price +'}';

    }

    }

    public static void main(String[] args) {

    /*

    * 构造方法引用

    */

    ConstructorRef constructorRef = Book :: new;

    Book book = constructorRef.createObject("Java",100.25);

    System.out.println(book);

    }

    总的来说Java 8一些新的特性在目前做的项目中还未大量使用,但是学习一下,到时也不至于看到这种Java 8新特性的代码而不知所错!

    感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

    展开全文
  • 引用,是变量的别名,就是你自己有个名字,比如李四,那你还有另外一个小名,叫小四,小四就是你的别名,别人叫你的时候你就会答应,那么李四和小四是同一个人,那么某个变量的引用是一样的,对该引用的操作就是对原...
  • 引用是使用最普遍的引用。如果一个对象具有强引用,那垃圾收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfM moryError错误,使程序异常终止,也不会靠随意回收具有强引用 对象来解决内存不足问题。 ...
  • 整体结构 ...当内存不足的时候,jvm 开始垃圾回收,对于强引用的对象,就算出现 OOM 也不会回收该对象的。 因此,强引用是造成 java 内存泄露的主要原因之一。 对于一个普通的对象,如果没有其他的引
  • 基础:C++的引用特点

    2020-05-14 11:42:09
    C++的引用1 内存分区模型1.1 程序运行前1.2 程序运行后1.3 new操作符2.1 引用的基本使用2.2 引用注意事项2.3 引用做函数参数2.4 引用做函数返回值2.5 引用的本质2.6 常量引用 1 内存分区模型 C++程序在执行时,将...
  • 搜索热词强引用在 Java 中最常见就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收,即使该对象以后永远都...
  • 在Java虚拟机中: ...对象的引用特点: 例: Person p2 = p; 如图所示,P和P2引用相同对象,对象的引用相当于把一个对象地址赋值给另一个对象变量。 因此,P2状态改变,同时也会改变p状态。 ...
  • String的特点 字符串不变:字符串的值在创建后不能被更改。 因为String对象是不可变的,所以它们可以被共享。 String的底层是char数组构成 String的创建方式 字符串的值不能被更改 String s1 = "abc"; s1 += "d"; ...
  • 关于C++中的引用类型(特点以及与指针区别) 今天上数据结构与算法课时,接触到了没有接触过C++中新概念——引用类型。也就是在函数形参部分前面加上&标识符,使得形参中地址得以copy下来,接下来便可以...
  • 引用在 Java 中最常见就是强引用,把一个对象赋给一个引用变量,这个引用变量就是一个强引用。当一个对象被强引用变量引用时,它处于可达状态,它是不可能被垃圾回收机制回收,即使该对象以后永远都不会被用到...
  • 基本数据类型:变量名指向具体数值引用数据类型:变量名指向存数据对象内存地址,即变量名指向hash值 二、从内存构建方面来说 基本数据类型:变量在声明之后java就会立刻分配给他内存空间 引用数据类型:它...
  • 1、Nodejs特点:单线程、Non-blocking I/O、Event Driven。 首先,Node不为每个用户开辟一个线程,所以非常极端选择单线程。单线程,要照顾所有用户,那么就必须要有非阻塞I/O,否则一个人I/O就把别人】自己...
  • 如果数据对象是一个比较大struct,则应该使用const指针或者const引用,来防止参数传递时发生结构体复制,导致程序效率下降; 如果数据对象时类对象,则使用const引用; 如果函数传参目的包括了修改传入...
  • c++的引用

    2018-03-17 18:17:20
    3.引用的特点 引用必须初始化 一个变量可以取多个别名(除const引用每个别名都可以修改这块地址的值) 引用只能在初始化的时候引用一次,不能改变为再引用其他的变量(例:b已经作为了a的别名了则它...
  • 引用

    2019-08-26 15:19:05
    引用的特点 1、定义时必须初始化 2、一个变量可以有多个引用 3、一个引用一旦引用了一个变量,就不能再引用其他变量了 引用比指针安全 引用不能更改 引用还可以做返回值 int func1(int &a) { return ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,628
精华内容 5,051
关键字:

引用的特点