我是靠谱客的博主 活泼学姐,最近开发中收集的这篇文章主要介绍16、Inner Class(内部类),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

    • 一、Note
      • 1、意义
      • 2、分类
        • 2.1、按照是否是成员来划分
        • 2.2、Java语言规范中的分类
      • 3、声明
        • 3.1、静态内部类(静态嵌套类)
        • 3.2、实例内部类(非静态嵌套类)
        • 3.3、局部内部类
        • 3.4、匿名内部类
        • 3.5、注意
      • 4、字节码文件的名称
      • 5、声明内部类类型变量
      • 6、创建内部类的实例
      • 7、不关注内部类的继承
    • 二、Code
      • 1、理解嵌套内部类和局部内部类的区别
        • Computer.java
        • ComputerTest.java
      • 2、在实例内部类中使用 外部类类名.this 来引用外部类的实例
        • CellPhone.java
        • CellPhoneTest.java
      • 3、创建实现了某个接口的匿名类的实例
        • Flyable.java
        • AnonymousClassTest1.java
      • 4、创建继承了某个抽象类并实现其中所有抽象方法的匿名类的实例
        • Human.java
        • AnonymousClassTest2.java
      • 5、创建继承了某个具体类的匿名类的实例
        • Aircraft.java
        • AnonymousClassTest3.java
      • 6、理解匿名类不能显式声明构造方法(但匿名类是有构造方法的)
        • AnonymousClassTest4.java
      • 7、匿名内部类应用举例:在实参中传入匿名类的实例
        • Printable.java
        • Store.java
        • StoreTest.java

一、Note

1、意义

  • 为了更好的封装

    • 为了实现更好的封装,普通类(非内部类)的访问修饰符不能为private或protected,而内部类可以。所以当我们将内部类声明为private时,就可对外隐藏内部类
  • 使Java的多继承机制变得更加完善

  • 每个内部类都能独立的继承或实现其他的类或接口,所以无论外部类是否已经继承或实现其他的类或接口,对于内部类都没有影响,内部类使得多继承的解决方案变得完整。

  • 方便编写线程代码

  • 方便编写事件驱动程序

  • 方便将存在一定逻辑关系的类组织在一起,又可以对外界隐藏

2、分类

2.1、按照是否是成员来划分

(按照是否在类体括号中声明来划分)

  • Nested Classes(嵌套类)

    • 静态嵌套类(静态内部类)
    • 实例嵌套类(实例内部类)
  • Local Classes(局部类)

    • 局部内部类
    • 匿名内部类
  • 嵌套类和局部类最重要的界限是作用域不同

    • 嵌套类的作用域是属于类的,嵌套类属于类的成员
    • 局部类的作用域是局部的
    • 所有的匿名内部类都是局部的

2.2、Java语言规范中的分类

  • 嵌套类

    • 静态嵌套类(被static修饰的成员内部类)
  • 内部类

    • 实例内部类

      • 没有被static修饰的成员内部类
      • 除了常量外,不能声明static修饰的字段;以及方法
    • 因此,实例内部类里可以定义静态变量[相当于常量]

  • 局部类

    • 在宿主类类体括号内部的某个局部区域中声明的内部类

    • 除了常量外,不能声明static修饰的字段;以及方法

      • 作用域是局部的
    • 匿名类

      • 不能显式指定类名
      • 因此,也不能显式声明构造方法
      • 但是创建匿名类的实例时,的确会调用父类的指定构造方法
      • 但是通过javac反编译匿名类得到结果可知,匿名类是有构造方法的,只是不公开
      • 除了常量外,不能声明static修饰的字段

3、声明

3.1、静态内部类(静态嵌套类)

public class Computer {
static class Brand { //在类中写,有static修饰
static int x;
}
}

3.2、实例内部类(非静态嵌套类)

public class Computer {
class Brand { //在类中写,没有static修饰
//static int x;
final static int x;
}
}
//内部类未加修饰符时,就是默认修饰符,包私有,外部类也可访问此内部类

3.3、局部内部类

  • 出了类之后就无法使用,有局部作用域的限制
public class Computer {
public void show() {
class Printer {
//static int x;
//static void hello(){}
//final static void hello(){}
final static int x;
}
}
}
或者:
public class Compuer{
{
class Printer{
}
}
}

3.4、匿名内部类

package cn.edu.ecut;
public class Computer{
public void welcome(){
// 以{}作为类体,继承Object类
Object o = new Object() {
//只有类体括号,不能显式指定类名

}
System.out.println(o.getClass());
}
public static void main(String[] args){
Computer c = new Computer();
c.welcome();//输出:class cn.edu.ecut.Computer$1
}

3.5、注意

  • 局部内部类和匿名内部类绝不会有static修饰,因为它们不是属于类的,它们属于局部代码块

4、字节码文件的名称

  • 嵌套类对应的字节码文件名称是 外部类类名$内部类类名.class
  • 局部内部类对应的字节码文件名称是 外部类类名$N内部类类名.class
    • 数字N指的是局部内部类在外部类的方法或代码块中出现的次数(顺序)
  • 匿名内部类对应的字节码文件名称是 外部类类名$N.class
    • 数字N指的是不同局部内部类在外部类的方法或代码块中出现的顺序
  • 注意:文件名把.class去掉,剩下的其实就是类名

5、声明内部类类型变量

  • 对于嵌套类来说,使用 外部类类名.内部类类名 来指定变量类型

    • 如:Computer.Brand brand = null ;
  • 对于局部类来说,只能在其作用域内部直接使用其类名来声明

    • 如:Printer p = null ;
  • 对于匿名内部类来说,因为不能显式指定匿名类的类名,所以也就不能声明匿名类类型的引用变量,但是可以声明匿名类所实现的接口类型的引用变量 或 匿名类所继承父类类型的引用变量

6、创建内部类的实例

  • 静态内部类(静态嵌套类)

    • 使用 new 外部类类名.内部类类名(参数) 形式来创建其实例
    • 如:Computer.Brand b = new Computer.Brand();
  • 实例内部类(非静态嵌套类)

    • 首先需要创建外部类类型的实例(比如Computer c = new Computer();)
    • 然后再在外部类的实例的基础上来创建实例内部类的实例(比如Computer.Mainboard m = c.new Minboard())
    • 即:Computer.Mainboard m = null; m = new Computer().new Mainboard();
  • 局部内部类

    • 直接在 其有效作用域{} 中使用new关键字创建即可
  • 匿名内部类

    • 创建实现了某个接口的匿名类的实例

      • 此时匿名类的直接父类是Object类
      • 此时匿名类实现了指定的接口(单个)
    • 创建继承了某个抽象类并实现其中所有抽象方法的匿名类的实例

      • 匿名类的直接父类就是相应的抽象类
      • 在创建匿名类实例时可以调用父类中带参数的构造方法
    • 创建继承了某个具体类的匿名类的实例

      • 匿名类的直接父类就是相应的具体类
      • 可以在匿名类中重写被继承类中的某些方法(根据需求来确定)
      • 在创建匿名类实例时可以调用父类中带参数的构造方法

7、不关注内部类的继承

  • 内部类主要是为了封装

二、Code

1、理解嵌套内部类和局部内部类的区别

Computer.java

package cn.edu.ecut;
// Computer 是个外部类,它对应的 字节码 文件是 Computer.class
public class Computer { // 电脑
// 直接在 外部类 的 类体括号中声明的 类,就是 嵌套类 ( Nested Classes )
// 嵌套类 也被称作 成员内部类
// 有 static 修饰的 嵌套类,也被称作 静态嵌套类 或 静态内部类
static class Brand { // 铭牌
// 对应的 字节码 文件名称是 Computer$Brand.class
}
// 没有 static 修饰的 嵌套类,也被称作 非静态嵌套类 或 非静态内部类 或 实例嵌套类 或 实例内部类
class Mainboard { // 主板
// 对应的 字节码 文件名称是 Computer$Mainboard.class
//static int x;//错误,因为x是类加载时就创建的,但是Mainboard内部类是创造一个类对象时才创建的
final static int x = 100; //定义一个常量是可以的
}
public void show() {
// 局部内部类
class Printer {
// 对应的 字节码 文件名称是 Computer$1Printer.class
}
Printer p = new Printer();
System.out.println( p );
}
public void hello() {
// 局部内部类
class Printer {
// 对应的 字节码 文件名称是 Computer$2Printer.class
}
Printer p = new Printer();
System.out.println( p );
}
//Object o = new Object() { };// 若放在类{}里面,也可以,但此时它不是成员内部类,它仍然是局部内部类,因为它只能用一次
public void welcome() {
Object o = new Object() {
// 只有类体括号、不能显式指定类名的局部内部类-匿名内部类
};
System.out.println( o.getClass() );
}
public void baby() {
Object o = new Object() {
};
System.out.println( o.getClass() );
}
public static void main(String[] args) {
Computer c = new Computer();
c.welcome(); // 输出:class cn.edu.ecut.Computer$1
c.welcome(); //class cn.edu.ecut.Computer$1
c.baby(); //class cn.edu.ecut.Computer$2
}
}

ComputerTest.java

package cn.edu.ecut;
public class ComputerTest {
public static void main(String[] args) {
// 声明 静态嵌套类 ( 静态内部类 ) 的 引用变量
Computer.Brand b =
null ;
// 创建 静态嵌套类 ( 静态内部类 ) 的实例
b = new Computer.Brand();
System.out.println( b );
// 获得 Brand 类的全限定名称
System.out.println( b.getClass().getName() );
// 获得 Brand 类的规范化名称(规范化类名),以原点隔开。对以后类加载有用(毕竟类加载的是类,不是文件==>把全限定名称即文件名中的$换为.)
System.out.println( b.getClass().getCanonicalName() );
System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
// m所指向的对象包围在c的对象内部,称作包围实例;
// Computer.Mainboard m= new Computer().new Mainboard();
// 声明 非静态嵌套类 ( 实例内部类 ) 的 引用变量
Computer.Mainboard m = null ;
// 创建 非静态嵌套类 ( 实例内部类 ) 的实例
Computer c = new Computer() ; // 首先创建外部类的实例
m = c.new Mainboard(); // 在 外部类实例 基础之上创建 实例内部类 实例
System.out.println( m ); //m.toString()形式,即m指向的对象的【类型(包名.类名)@地址】
System.out.println( m.getClass().getName() ); // 全限定名称
System.out.println( m.getClass().getCanonicalName() ); //规范化名称
}
}

输出:

cn.edu.ecut.Computer$Brand@4d591d15
cn.edu.ecut.Computer$Brand
cn.edu.ecut.Computer.Brand
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
cn.edu.ecut.Computer$Mainboard@6a6824be
cn.edu.ecut.Computer$Mainboard
cn.edu.ecut.Computer.Mainboard

2、在实例内部类中使用 外部类类名.this 来引用外部类的实例

CellPhone.java

package cn.edu.ecut;
public class CellPhone {
public String brand = "一加" ;
public class Screen {
String brand = "京东方" ;
public void show() {
String brand ="";
// 在 实例内部类 中 使用 this 可以引用 该实例内部类的当前实例
// 有this.则brand指的是“京东方”;没有this.则brand指的是“”
System.out.println( this.brand );
// 通过 "外部类类名.this.字段名" 来引用外部类的实例变量
System.out.println( CellPhone.this.brand );
}
public CellPhone getOuter() {
// 在 实例内部类 中 可以使用 "外部类类名.this" 来引用 外部类的 当前实例
return CellPhone.this ;
}
} // end : Screen
public static class A{
public void show(){
//System.out.println(CellPhone.this); // 错误
//静态内部类只能访问静态成员,不能访问外部类的实例(非静态成员);实例内部类可以访问外部类的实例,不能访问静态成员
}
}
/*
static class B{
CellPhone p = new CellPhone();
}
此代码有些问题,若没有 static,则更加极有可能造成内存溢出,因为在创建实例(new CellPhone())时,就会产生B这个类,但无法确定产生多少B这个类
class B{
CellPhone p = new CellPhone();
}
*/
}

CellPhoneTest.java

package cn.edu.ecut;
public class CellPhoneTest {
public static void main(String[] args) {
/*
// 引用变量 p 指向了 一个 CellPhone 类型的实例
CellPhone p = new CellPhone();
// 引用变量 s 指向了一个 Screen 类型的实例
CellPhone.Screen s = p.new Screen();
*/
// 创建 实例内部类 Screen 类的实例
CellPhone.Screen s = new CellPhone().new Screen(); // 标记
System.out.println( s );
s.show();
// 用p接收外部类 CellPhone的实例
CellPhone p = s.getOuter(); // 此处的p不是重新new出来的,是在“标记”这行new的这两个实例时就存在的,当时创建外部类Cellphone的实例是什么,p就接收什么
System.out.println( p );
}
}

输出:

cn.edu.ecut.CellPhone$Screen@65ae6ba4
京东方
一加
cn.edu.ecut.CellPhone@7960847b

3、创建实现了某个接口的匿名类的实例

Flyable.java

package cn.edu.ecut;
public interface Flyable {
void fly();
}

AnonymousClassTest1.java

package cn.edu.ecut;
import java.util.Arrays;
/**
* 【最常见的应用】使用 匿名类 实现 接口,并创建该类的实例
*/
public class AnonymousClassTest1 {
public static void main(String[] args) {
// 声明 Flyable 类型的引用变量,并将 null 赋值给该变量
Flyable f = null ; // 引用变量 f
的 编译时类型 是 Flyable
// f = new Flyable() ; // 接口都没有构造方法,也不能被实例化
// 形式上,似乎是在通过 new 关键字 创建 Flyable 接口的实例 【尸体】
// 本质上,创建一个实现了 Flyable 接口的 匿名类 的实例
【借尸还魂】
// {}作为一个类体,实现了接口,实现了接口里的抽象方法
f = new Flyable() { // 匿名类开始
【魂】
@Override
public void fly() { // 在匿名类中实现 Flyable 接口中所有的抽象方法
System.out.println( "飞飞飞,在梦里飞,想飞哪里飞哪里" );
}
}; // 匿名类结束
f.fly();
/*
//匿名内部类只使用这一次;若想再次使用这个类的实例,则需要再写一个匿名类,或者可以重新声明一个类实现接口
f = new Flyable() {
@Override
public void fly() {
System.out.println( "飞飞飞,在梦里飞,想飞哪里飞哪里" );
}
};
//若是再写了一个匿名类,则此时字节码文件有:
//AnonymousClassTest1$1.class,AnonymousClassTest1$2.class
*/
Class<?> c = f.getClass() ;
// 获得运行时类型
System.out.println( c.getName() ); // 全限定名称-cn.edu.ecut.AnonymousClassTest1$1
System.out.println( c.getCanonicalName() ); // 规范化类名 ( 注意这里是 null )
// 匿名内部类不能显式书写类名,因此输出类名为null
Class<?> p = c.getSuperclass(); // 获得 c 所表示类型的父类
System.out.println( p.getName() ); //java.lang.Object
// 获得 c 所表示的类所实现的接口 (或 c所表示的接口 所继承的接口)
Class<?>[] interfaces = c.getInterfaces();
System.out.println( Arrays.toString( interfaces ) );
//此处调用的是Arrays/toString(Object[] a),Class是Object的子类,因此可直接写Class类型的
}
}

输出:

飞飞飞,在梦里飞,想飞哪里飞哪里
cn.edu.ecut.AnonymousClassTest1$1
null
java.lang.Object
[interface cn.edu.ecut.Flyable]

4、创建继承了某个抽象类并实现其中所有抽象方法的匿名类的实例

Human.java

package cn.edu.ecut;
public abstract class Human {
public String name ;
public Human() {
super();
System.out.println( "Human()" );
}
public Human( String name ) {
super();
this.name = name ;
System.out.println( "Human( String )" );
}
public abstract void eat( String food );
}

AnonymousClassTest2.java

package cn.edu.ecut;
/**
* 创建继承了某个抽象类并实现其中所有抽象方法的匿名类的实例
*/
public class AnonymousClassTest2 {
public static void main(String[] args) {
Human h = null ;
// h = new Human( "张三丰" ); // 抽象类有构造方法,但是抽象类不能实例化
// 形式上,似乎是在通过 new 关键字 创建抽象类 Human 的实例 【尸体】
// 本质上,创建一个继承了 Human 类 并实现了其中所有抽象方法的 匿名类 的实例
【借尸还魂】
h = new Human(
"张三丰" ) { // 匿名类开始 【魂】
@Override
public void eat(String food) { // 重写抽象类中的抽象方法
System.out.println( this.name + "吃" + food );
}
} ; // 匿名类结束
h.eat( "西瓜" );
System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
h = new Human() {
@Override
public void eat(String food) {
System.out.println( this.name + "吃" + food );
}
};
h.name = "张君宝" ;
h.eat( "冬瓜" );
}
}

输出:

Human( String )
张三丰吃西瓜
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
Human()
张君宝吃冬瓜

5、创建继承了某个具体类的匿名类的实例

Aircraft.java

package cn.edu.ecut;
public class Aircraft {
public String type ;
public Aircraft(){
super();
}
public Aircraft( String type ){
super();
this.type = type ;
}
public void fly() {
System.out.println( "飞行中..." );
}
public void travel() {
System.out.println( "行驶中..." );
}
}

AnonymousClassTest3.java

package cn.edu.ecut;
import java.util.Arrays;
/**
* 1、创建继承了某个具体类的匿名类实例
* 2、可以在匿名类中重写被继承类中的某些方法
*/
public class AnonymousClassTest3 {
public static void main(String[] args) {
Aircraft a = new Aircraft();
a.fly();
a.travel();
System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
Aircraft b = new Aircraft() { } ; // 父类引用 指向 子类对象 ( 因为最后的 { } 就是一个匿名类的类体 ),子类即为匿名类
System.out.println( b.getClass() );
System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
// 调用 父类无参数构造方法
Aircraft c = new Aircraft() {
// 在匿名类中声明实例变量
String name = "航天飞机" ;
@Override
public void fly() { // 重写从父类 中继承的 fly 方法
System.out.println( this.name + "正在飞行" );
}
} ;
c.fly(); // 调用重写后的方法
System.out.println( c.getClass() );
System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
// 调用 父类有参数构造方法
Aircraft d = new Aircraft( "飞船" ) {
// 在匿名类中声明实例变量
String name = "嫦娥二号" ;
@Override
public void fly() { // 重写从父类 中继承的 fly 方法
System.out.println( this.name + this.type + "正在月球上空飞行" );
}
} ;
d.fly(); // 调用重写后的方法
System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
Class<?> cc = d.getClass() ;
// 获得运行时类型
System.out.println( cc.getName() ); // 全限定名称
System.out.println( cc.getCanonicalName() ); // 规范化类名 ( 注意这里是 null )
Class<?> p = cc.getSuperclass(); // 获得 cc 所表示类型的父类
System.out.println( p.getName() );
Class<?>[] interfaces = cc.getInterfaces(); // 获得 cc 所表示的类所实现的接口
System.out.println( Arrays.toString( interfaces ) );
}
}

输出:

飞行中...
行驶中...
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
class cn.edu.ecut.AnonymousClassTest3$1
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
航天飞机正在飞行
class cn.edu.ecut.AnonymousClassTest3$2
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
嫦娥二号飞船正在月球上空飞行
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
cn.edu.ecut.AnonymousClassTest3$3
null //匿名类在语言规范中不能显式书写类名,因此输出null
cn.edu.ecut.Aircraft
[] //说明没有实现任何接口,因为匿名类直接继承了父类Aircraft.java

6、理解匿名类不能显式声明构造方法(但匿名类是有构造方法的)

AnonymousClassTest4.java

package cn.edu.ecut;
import java.lang.reflect.Constructor;
import java.util.Arrays;
/**
* 尝试获取匿名类的构造方法
*/
public class AnonymousClassTest4 {
public static void main(String[] args) {
// 在 java.lang.Cloneable 接口中没有声明任何方法
Cloneable c = new Cloneable() { // 创建 实现了接口Cloneable的 匿名类实例
// 这里什么都不用写
};
/*
// {}作为一个类体,继承了父类Human,调用父类Human中的带参数构造(通过匿名类中的带参构造调用父类构造,匿名类中的带参构造中第一行为:super("张翠山");,只不过匿名类中的构造对我们不可见)
Human c = new Human( "张翠山" ) { // 创建 继承了具体类Human的 匿名类实例
@Override
public void eat(String food) {
}
};
*/
System.out.println( c );
System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
Class<?> clazz = c.getClass();
// 通过 反射 来获取 匿名类 中所有的构造方法组成的数组
Constructor<?>[] constructors = clazz.getDeclaredConstructors();
System.out.println( Arrays.toString( constructors ) );
}
}

输出:

cn.edu.ecut.AnonymousClassTest4$1@4d591d15
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
[cn.edu.ecut.AnonymousClassTest4$1()]
//获取到一个无参的构造
若换成注释里的内容,并且将Cloneable一行注释,则输出:
Human( String )
cn.edu.ecut.AnonymousClassTest4$1@4aa8f0b4
~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
[cn.edu.ecut.AnonymousClassTest4$1(java.lang.String)]

7、匿名内部类应用举例:在实参中传入匿名类的实例

Printable.java

package cn.edu.ecut;
// 打印接口
public interface Printable {
// 打印
void print( String content );
// 复印
String copy( String content );
}

Store.java

package cn.edu.ecut;
public class Store {
public void print( Printable p , String content ) {
p.print(content); // 这里调用的是 Printable 实例的 print 方法
}
public String copy( Printable p , String content ) {
return p.copy(content) ; // 这里调用的是 Printable 实例的 copy 方法
}
}

StoreTest.java

package cn.edu.ecut;
public class StoreTest {
public static void main(String[] args) {
Store s = new Store();
// 方法一:传入匿名类实例
Printable p = new Printable() { // 引用变量p指向 实现了接口Printable的 匿名内部类的对象
String name = "HP打印机" ; // 匿名类的实例变量
@Override
public void print(String content) {
System.out.println( this.name + " 正在打印 " + content );
}
@Override
public String copy(String content) {
System.out.println( this.name + " 正在复印 " + content );
String s = new String( content );
return s ;
}
};
s.print( p , "犯我中华者虽远必诛" );
// 方法二:传入匿名类实例
s.print( new Printable() {
String name = "爱普生打印机" ; // 匿名类的实例变量
@Override
public void print(String content) {
System.out.println( this.name + " 正在打印 " + content );
}
@Override
public String copy(String content) {
System.out.println( this.name + " 正在复印 " + content );
String s = new String( content );
return s ;
}
} ,
"犯我中华者虽远必诛" );
}
}

输出:

HP打印机 正在打印 犯我中华者虽远必诛
爱普生打印机 正在打印 犯我中华者虽远必诛

最后

以上就是活泼学姐为你收集整理的16、Inner Class(内部类)的全部内容,希望文章能够帮你解决16、Inner Class(内部类)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部