Java基础-new一个在不同个包中且只有protected构造方法的类的对象(匿名内部类的使用)

目录

前言

  如何new一个在不同个包中且只有protected构造方法的类的对象呢?在讲解如何实现之前,来讲一下事情的缘由。下面将说明如何实现(这里主要讲的是如何使用匿名内部类实现)。后续描述的内容如有问题请广大读者能够耐心指出,给读者带来不便之处,还请见谅。
  在使用gson解析json字符串的时候,使用到如下代码:

Gson gson = new Gson();
List<OrderDetail> orderDetailList = new ArrayList<>();
orderDetailList = gson.fromJson(orderForm.getItems(), new TypeToken<List<OrderDetail>>() {}.getType());

  其中最引人注目的当属,这部分代码:

new TypeToken<List<OrderDetail>>() {}.getType()

  这里使用了匿名内部类(且内部未做任何操作),查看TypeToken类源码会发现,该类中只存在一个使用protected修饰的无参构造方法,在正常情况下,我们使用在不同的包中new出这样的对象(当然我指的是new的使用调用的构造方法是使用protected修饰的。),那么这里已经教我们如何处理了,即采用匿名内部类。

实现过程

  为更好的描述一个实现过程,我们先来创建一个类,SupperClass,且位于com.wm103.test包中,如下:

package com.wm103.test;

public class SupperClass {
    private String message;

    protected SupperClass() {
        System.out.println("supper class init.");
    }

    public void print() {
        System.out.println("This is supper class.");
        System.out.println("message: " + this.getMessage());
    }

    public String getMessage() {
        return this.message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

  我们再来创建一个主类,MainClass,且位于com.wm103包中,如下:

package com.wm103;

import com.wm103.test.SupperClass;

public class MainClass {

    public static void main(String[] args) {
        new SupperClass();
    }
}

  直接new SupperClass(),我想你会在IDE中看到类似这样的提示:

'SupperClass()' has protected access in 'com.wm103.test.SupperClass'

  因为SupperClass()构造方法是protected访问权限,而MainClassSupperClass不在同个包中,所以并不能直接new SupperClass()。那么我们该怎么做呢?采用匿名内部类。如下:

new SupperClass() {}.print();

  在这样的情况下,我们即可创建匿名内部类对象,且调用SupperClass类的print方法。

扩展

  匿名内部类中是不能定义构造函数的。而我们一般都是利用构造器来完成某个实例的初始化工作的,那么在匿名内部类中我们应该如何实现初始化操作呢?使用构造代码块!利用构造代码块能够达到为匿名内部类创建一个构造器的效果。
  还是以上述中的例子为例,如下:

new SupperClass() {
    {
        setMessage("Hello Supper Class.");
        innerPrint();
    }

    public void innerPrint() {
        System.out.println("This is inner class.");
    }
}.print();

  在上述的匿名内部中,定义了构造代码块用来实现初始化操作,还定义了一个属于自己的方法。运行这样的例子,将在控制台看到这样的输出结果:

supper class init.
This is inner class.
This is supper class.
message: Hello Supper Class.

  具体流程如下:调用SupperClass的构造方法进行初始化 -> 运行匿名内部类的构造代码块 -> 调用print方法(方法内输出了在构造代码块初始化的message的值)。
  如果在匿名内部中定义与SupperClass中同名的方法,又会将如何呢(会发生方法覆盖),如下:

new SupperClass() {
    {
        setMessage("Hello Supper Class.");
        innerPrint();
    }

    public void innerPrint() {
        System.out.println("This is inner class.");
    }

    public void print() {
        System.out.println("inner class::print");
    }
}.print();

  运行结果如下:

supper class init.
This is inner class.
inner class::print

知识点扩展或参考

猜你喜欢

转载自blog.csdn.net/qq_15096707/article/details/81146526