匿名对象

顾名思义,匿名对象指的就是没有名字的对象,在使用中理解为实例化一个类对象,但是并不把它赋给一个类变量,而是直接使用。匿名对象具有以下特征:

  1. class Student{
  2. String name;
  3. public void showInfo(){
  4. System.out.println("Name is: " + this.name);
  5. }
  6. }
  • 语法上:只创建对象,但不用变量来接收,例如:假设现在有个Student类如上所示,通常情况我们在使用这个类时需要先实例化类对象,然后调用类的属性和方法```java Student s = new Student(); s.name = “Forlogen”; s.showInfo(); // Forlogen

    1. <br />而匿名类并不使用变量接收直接使用```java
    2. System.out.println(new Student().name)
  • 匿名对象的使用:

    • 匿名对象本质上仍然是一个对象,所以它具备对象的所有功能
    • 每次创建一个匿名对象都是一起全新的对象,即每次创建的匿名对象都是不同的对象,它们在堆内存中具有不同的地址。而且一个匿名对象只能使用一次。这怎么理解呢?同样假设现在想使用Student这个类,每次实例化匿名对象得到的都是新的对象:java // 第一个匿名对象 public class AnonymousTest { public static void main(String[] args) { System.out.println(new Student().name = "Kobe"); // Kobe System.out.println(new Student().name); // null }
      从输出中可以看出,前后两个实例化的匿名对象是不同的,第一个我们为其进行赋值,打印出的就是赋值的结果;而第二个并没有对name属性就行赋值,那么返回的就是String类型的默认值null。


既然匿名对象只能使用一次,那么它有哪些应用场景呢?常用到匿名对象的有如下几个:

  • 只想调用匿名对象的方法,例如在使用Scanner类获取键盘输入时,我们常这样做:```java Scanner sc = new Scanner(System.in); // 10 int num = sc.nextInt();
    System.out.println(num); //10

    1. <br />而如果只想输出从键盘获取的值,就可以使用匿名对象```java
    2. System.out.println(new Scanner(System.in).nextInt());
  • 直接使用匿名对象作为方法的参数和返回值```java // 将匿名对象作为返回值 public class AnonymousTest { public static void main(String[] args) { int n = getScanner().nextInt(); System.out.println(n); }

    public static Scanner getScanner(){ return new Scanner(System.in); } }

    1. ```java
    2. // 将匿名对象作为函数参数
    3. public class AnonymousTest {
    4. public static void main(String[] args) {
    5. Scanner sc1 = new Scanner(System.in);
    6. getScanner(sc1);
    7. }
    8. public static void getScanner(Scanner sc){
    9. System.out.println(sc.nextInt());
    10. }
    11. }

缺点:一个匿名对象只能使用一次,造成内存空间的浪费。
image-20200418094206942.png

如上所示,当我们依次实例化三个Student类的匿名对象时,每次实例化一个匿名对象,JVM就要在堆中为其开辟一块新的空间,当这行代码执行完毕内存就会被回收;然后再实例化新的对象时 ,JVM又会为其开辟新的空间,其他类似。

优点:

  • 由于匿名对象不需要在实例化后赋给变量,因此当大量需要使用匿名对象时,可以节省保存变量所需的栈空间
  • JVM的垃圾回收会根据对象是否可达来判断是否为垃圾,如果不可达,则在下一次的垃圾回收中进行回收。而匿名对象创建后只能使用一次,当使用结束后它就是垃圾了,这样便于JVM快速回收,节省堆内存空间。

实验代码:

package com.company;

import java.util.Scanner;

class Student{
    String name;

    public void showInfo(){
        System.out.println("Name is: " + this.name);
    }
}

public class AnonymousTest {
    public static void main(String[] args) {
        Student s = new Student();
        s.name = "Forlogen";
        s.showInfo();

        System.out.println(new Student().name = "Kobe");
        System.out.println(new Student().name);

        Scanner sc = new Scanner(System.in);
        int num = sc.nextInt();
        System.out.println(num);

        System.out.println(new Scanner(System.in).nextInt());
        int n = returnScanner().nextInt();
        System.out.println(n);

        Scanner sc1 = new Scanner(System.in);
        getScanner(sc1);

    }

    public static Scanner returnScanner(){
        return new Scanner(System.in);
    }

    public static void getScanner(Scanner sc){
        System.out.println(sc.nextInt());
    }
}