技术交流


JAVA核心技术基础学习笔记

Mar 12, 2019 9:55:18 AM
100
34

java概述

java“白皮书”关键术语

1.      简单性、面向对象、分布式、健壮性、安全性、体系结构中立、可移植性、解释性、高性能、多线程、动态性。

2.      在网页中运行的java程序叫applet。

java基础程序设计结构

数据类型

1.      整型

int(4字节 32位)、short(2字节 16位)、long(8字节 64位)、byte(1字节 8位)。

long有一个后缀L或l,(如4000000000L);十六进制数值有前缀0x或0X(如0xCAFE);八进制有前缀0(如010代表8),易混淆,不建议使用八进制。

1.      浮点型

float(4字节)、double(8字节)。

float的数值有一个后缀F或f(如3.12f);如果3.12没有后缀默认为double型,double型也可加后缀D或d。

三个表溢出或出错的浮点型:正无穷大,负无穷大,NaN。

如果在数值计算中不允许任何舍入误差,就用BigDecimal类。

Double.isNaN(x)//判断不是数字。

1.      char

有些Unicode字符用char值描述,另些Unicode字符需要两个char表示。

码点:是指一个编码表中的某个字符对应的代码值。

代码单元:在基本的多语言级别中,每个字符用16位表示,称为代码单元;辅助字符采用一对连续的代码单元。

2.      boolean

整型和boolean之间不能相互转换。

变量

常量

利用关键字final指示常量,习惯上常量名全大写。(如final double NUM = 2.23)。

运算符

 API: Math类

运算符:+、-、*、/、等

数学函数与常量

在Math类中,提供了三角函数,指示函数,π等各式各样的数学函数和常量(如开方Math.sqrt(x)、Math.PI)。

数值之间的类型转换

如果两个数中有一个double,另一个就会转为double;否则其中一个为float,另一个转为float;否则其中一个为long,另一个转为long;否则另个都将转为int。

括号与运算级别

+=是右结合运算,所以表达式a += b += c等价于a += (b += c)

 字符串

API:java.lang.String、java.lang.StringBuffer、java.lang.StringBuilder

拼接

       用指定符号将多个字符串拼接成新字符串用静态的join()方法。

如:String all = String.join("/","a","cc","s");

不可变字符串

优点:编译器可让字符串共享。

构建字符串

        StringBuilder(效率高,线程不安全)前身是StringBuffer(线程安全)。

控制流程

块作用域

不能在嵌套的两个块声明相同变量名,如下:

{

int n;

...

{

int n;

...

}

}

条件语句

if(condition){

statement

...

}

 

if(condition){

statement

....

}else{

statement

...

}

 

if(condition){

statement

....

}else if(condition){

statement

...

}else{

statement

...

}

循环

while(condition){

statement

...

}

 

do{

statement

...

}while(condetion);

多重选择

switch(param){

case v1:

...

break;

case v2:

...

break;

case v3:

...

break;

default:

...

break;

}

注意:case标签可以是:

1.      类型为char、byte、short、int的常量表达式。

2.      枚举常量。

3.      java SE7开始也可以是字符串字面量。

大数值

API:java.math.BigInteger、java.math.BigDecimal

如果基本的整数和浮点数精度不能满足要求,可使用java.math包的BigInter和BigDecimal(如金额)。

使用静态的valueOf方法可以将普通数值转为大数值(如BigInteger a = BigInteger.valueOf(100);)。

大数值不能用算术运算符(+、-、*、/等),必须使用大数值类中的方法处理大数值(如一个加法运算: BigInteger c = a.add(b);等价于c = a + b;)。

数组

API:java.util.Arrays

for each循环

for(variable : conllection) {statement...}

数组拷贝

Arrays.copyOf(oldArray,oldArray.length);

快速打印数组

1.      Arrays.toString(a)

2.      二维数组:Arrays.deepToString(a);

对象与类

OOP概述

类是构造对象的模板和蓝图。

封装:实现封装的关键在于决不让类中的方法直接访问其他类的实例域(对象中的数据)。程序仅通过对象的方法与对象数据之间进行交互。

对象

对象的三个特性:

1.      行为:可调用的方法。

2.      状态:只能通过调用方法来改变。

3.      标识:每个对象都不同,状态也常常不一样。

类与类之间的关系

    1.      依赖:A类的方法操纵B类的对象,A类依赖于B类。

    2.      聚合:A对象包含B对象。

    3.      继承:A类扩展B类,并且A类添加自己的额外功能。

预定义类

API:java.time.LocalDate

对象与对象变量

使用构造器构造一个新对象,关键字new。

任何对象变量的值都是对存储在另一个地方的一个对象的引用。new操作的返回值是一个引用。一个方法不能作用于一个值为null的对象上。

局部变量不会自动初始化为null,必须通过new或设置为null。

LocalDate

Date类:表时间点。

LocalDate类:日历表示法,用于维护日期;使用静态工厂方法代表调用构造器,而不是new关键字(如:LocalDate.now();//表构造这个对象的日期)。

用户自定义类

源(类)文件名必须与public类名字相匹配;在一个源文件中,只能有一个公共类,但可以有任意多的非公共类。

构造器

构造器与类同名,不要在构造器中定义与实例域同名的变量。

隐式参数与显式参数

1.      隐式参数:出现在方法名前的类对象(如User.add(x)中的User对象)。在每个方法中this表示隐式参数。

2.      显式参数:方法名后括号中的值为显式参数(如User.add(x)中的x)。

封装的优点

封装一般需要三项类容:

1.      一个私有的数据域。

2.      一个共有的域访问器方法。

3.      一个共有的与更改器方法。

优点:数据域改变内部实现,不会影响其他类代码。更改器方法可以检验数据域的合法性。

注意:不要编写返回引用可变对象的访问构造器;解决,先对可变数据域(可变对象)克隆再返回。

私有方法

一个计算代码划分成若干独立的辅助方法,这些辅助方法可设为私有方法。这是由于他们往往与当前实现机制非常紧密,或需要一个特别的协议以及一个特别的调用次序。

静态域与静态方法

静态域

如果将域定义为static,每个类中只能有一个这样的域。它属于类,不属于任何独立对象。

静态常量

一般设为公有。

静态方法

静态方法不能向对象实施操作方法,即没有隐式对象或没有this参数的方法。

静态方法可以访问自身的静态域。

可以通过类名和对象调用。

什么时候使用静态方法:

1.      一个方法不需要访问对象状态,所需参数都是显式参数提供。

2.      一个方法只需访问类的静态域。

工厂方法

可以使用静态工厂方法构造对象

为什么有时不用构造器实例

3.      无法命名构造器(构造器名与类名不同)。

4.      当使用构造器时,不能够改变所构造的对象类型。

main方法

        main方法将执行并创建所需对象

方法参数

方法得到的是对象引用的拷贝,对象引用及其他拷贝同时引用同一个对象。java对对象采用的不是引用调用,对象引用是按值传递的。

对象构造

重载

返回类型不是方法签名的一部分。即不能有两个名字相同、参数类型也相同却返回值不同类型值的方法。

无参构造器

无参构造器将所有实例域设为默认值。

如果类中至少有一个有参构造器,却没有无参构造器,则不能使用无参构造器实例对象。

显式域初始化

显式域初始化值不一定是常量,也可以是调用一个方法。

调用另一个构造器

关键字this不仅是引用方法的隐式参数;还可以通过this(...)调用同一个类的另一个构造器。这样可以对公共的构造器代码只写一次。

初始化块

只要构造类对象,这些块就会被执行。即先运行初始化块,再运行构造器主体部分。

 初始化数据域的方法

1.      在构造器中设置。

2.      在声明中赋值。

3.      在初始化块中设置。

可以提供静态域的初始值;但如果对类的静态域初始化代码比较复杂,也可以使用一个静态初始化块(static{})初始化。

对象析构与finalize方法

java有自动的垃圾回收器,不需人工回收内存,所以java不支持析构器。

如果某个资源需要在使用完毕后立刻关闭,那么就需要人工来管理。对象用完时,可以应用一个close方法来完成相应的清理操作。

finalize方法将在垃圾回收器清除对象之前调用。

java允许用包将类组织起来。所有标准的java包都处于java和javax包层次中。

类的导入

一个类可以使用所属包中的所有类,以及其他包中的公有类。

静态导入

import不仅可以导入类,还增加了导入静态方法和静态域的功能。

包作用域

如果没有指定public或private,这个部分(类、方法、或变量)可以被同一个包中的所有方法访问。

类路径

类路径:类路径是指所有包含类文件的路径集合。

编译器任务

1.      定位文件(如定位一个类导入的其他类的类文件)。

2.      查看源文件是否比类文件新,如果新,源文件会自动重新编译。

类设计技巧

1.      一定要保证数据私有。

2.      不要在类中使用过多的基本类型。

3.      不是所有的域都需要域访问器或域更改器。

4.      将职责过多的类进行分解。

5.      类和方法名要能体现他们的职责。

6.      有限使用不可变的类。

类、超类、子类

子类构造器

如果子类构造器没有显式的调用超类构造器,将自动调用超类默认构造器。如果超类没有不带参数的构造器,并且在子类构造器有没有显式的调用超类的其他构造器,将编译报错。

super关键字作用

1.      调用超类方法。

2.      调用超类的构造器。

 

调用构造器的语句只能出现在另一个构造器的第一句。

一个对象变量可以指示多种实际类型的现象称为多态。在运行时能够自动的选择调用哪个方法的现象称为动态绑定

继承层次

有一个公共超类派生出来的所有类集合称为继承层次。在继承层次中,某个特定的类到其祖先的路径称为该类的继承链

多态

一个类变量既可以引用一个类对象,也可与引用其的任何一个子对象。但是,不能将一个超类的引用赋给子类变量。

方法调用

重载解析:编译器根据参数找到调用的对应的重载方法的过程。

:允许子类将覆盖方法的返回类型定义为原返回类型的子类型。

private方法,static方法、final方法或者构造器,这些“方法”编译器可以准确的知道该调用哪个方法,这种调用方式称为静态绑定

虚拟机会预先为每个类创建一个方法表,其中列出了所有方法的签名和实际调用的方法。这样一来,在真正调用方法的时候虚拟机仅查找这张表。

动态绑定的特性:无需对现存代码进行修改,就可以对程序进行扩展。

      警告:在覆盖一个方法的时候,子类方法不能低于超类方法的可见性。

阻止继承:final类和方法

类的特定方法被声明为fina,子类将不能覆盖这个方法。

如果将类声明为final,只有其中的方法自动成为final,而不包括域。

强制类型转换

只能在继承层次内进行转换。在将超类转换成子类前,应该用instanceof进行检查。

抽象类

类即使不含抽象方法,也可以将类声明为抽象类。抽象类不能被实例化。

可以定义一个抽象类的对象变量,但是它只能引用非抽象子类的对象。

编译器只允许调用声明在类中的方法。

受保护访问

java用于控制可见性的4个访问修饰符

1.      仅对本类可见——private。

2.      对所有类可见——public。

3.      对本包和多有子类可见——protected。

4.      对本包可见——默认,不需要修饰符。

Object类:所有类的超类

equals方法

Object类中的equals方法用于检验一个对象是否等于另一个对象。

相等测试与继承

从不同情况设计equals方法

1.      如果子类能够拥有自己相等的概念,则对称性需求经强制性采用getClass进行检测。

2.      如果由超类决定相等的概念,那么就可以使用instanceof进行检测,这样可以在不同子类对象之间进行相等比较。


            假设某个超类的id作为相等检测标准,并且这个相等概念适用于所有子类,就可以适用instanceof进行检测,并且应该将类名.equals方法声明为final。

编写完美equals方法建议

1.      显示参数名为otherObject。

2.      检测this和otherObject是否引用同一个对象。

3.      检测otherObject是否为null,如果为null,返回false。

4.      比较this与otherObject是否属于同一个类。

5.      将otherObject转换为相应的类类型变量。

6.      现在进行比较。

如果在子类重新定义equals方法,就要在其中调用super.equals(other)。

对于数组类型的域,可以使用静态的Arrays.equals方法检测相应的数组元素是否相等。

hashCode方法

API:java.util.Object、java.util.Objects、java.lang.基本数据类型的包装类、java.util.Arrays;这些类的hashCode相关方法。

散列码:是由对象导出的一个整形值。

由于hashCode方法定义在Object类中,因此每个对象都有一个默认的散列码,其值为对象的存储地址。如果重新定义equals方法,就必须重新定义hashCode方法,以便用户可以将对象插入到散列表中。最好使用null安全的方法Objects.hashCode。基本数据类型使用包装类名.hashCode来避免创建包装类对象。

equals和hashCode的定义必须一致,如果x.equals(y)放回true,那么x.hashCode()就必须与y.hashCode()相同。

      如果存在数组类型的域,那么可以使用静态的Arrays.hashCode方法计算一个散列码,这个散列码由元素的散列码组成。

toString方法

API:java.lang.Object的toString方法和eaqals方法,在自定义的类中,应该覆盖这两个方法。

toString只要目的:只要一个对象与一个字符串通过操作符“+”连接起来,java就会自动的调用toString方法,以便获得这个对象的字符串描述。

在调用x.toString方法时可以用""+x代替。如果x是基本类型,这条语句照样能执行。

Object类定义了toString方法,用来打印输出对象所属的类名和散列码。

泛型数组列表

API:java.util.ArrayList<E>

ArrayList:是一个采用类型参数的泛型类。

使用add方法可以将元素添加到数组列表中。数组列表管理着对象引用的一个内部数组。如果调用add且内部数组已经满了,数组列表就会自动创建一个更大的数组,并将所有的对象从较小的数组中拷贝到较大的数组中去。

访问数组列表元素

API:java.util.ArrayList<T>

使用add方法数组添加新元素(可以插入中间元素),而不用set方法,set方法会覆盖已经存在的元素内容。

对数组实施插入和删除的效率比较低;如果数组储存元素比较多,就应该使用链表。

类型化与原始数组的兼容性

一旦能保证不会造成严重后果,可以用@SuppressWarnings("unchecked")标注来标记完成这个变量能够接受类型转换。如下:

@SuppressWarnings("unchecked")

      ArrayList<A> res = (ArrayList<A>) a.find(b);//fields warning.

对象包装器与自动装箱

API:java.lang.Integer、javaj.lang.NumberFormat

所有基本类型都有一个对应的包装(器)类;整形和浮点型的包装器的公共超类Number。对象包装类是不可变的,即一旦构造了包装器,就不允许改变包装在其中的值。对象包装器还是final,因此不能定义它们的子类。

警告:由于每个值分别包装在对象中,所以ArrayList<Integer>的效率远低于int[]的效率,因此乐意用它构造小型集合。

自动装箱,如:list.add(3);自动转为list.add(Integer.valueOf(3));

两个包装类比较时,用equals方法。

如果在一个条件表达式中混合使用Integer和Double类型,Integer值就会拆箱,提升为double,再装箱为Double。

拆箱和装箱是编译器认可的,而不是虚拟机。编译器在生成类的字节码时,插入必要的方法调用。虚拟机只是执行这些字节码。

参数数量可变方法

如:public static String method(String a,Object... args){

....

......

}

“...”是java代码的一部分,它表明这个方法可以接受任意数量的对象(除a参数外)。

可以这样调用此方法:

String m = method("cc",1,"bb","xx");编译器经new Object[]{1,"bb","xx"}传递给method方法。

枚举类

API:java.lang.Enum<E>

一个简单的枚举类:

public enum Size(){

SMALL,MEDIUM,LARGE,EXTRAL_LARGE

}

在比较两个枚举类型是相等时,永远不要调用equals方法,而直接使用“==”就可以了。

如果需要的话,可以在枚举类型中添加一些构造器、方法和域;构造器只是在构造枚举时调用。

      所有的枚举类型都是Enum的子类。

反射

API:java.lang.Class、java.lang.reflect.Constructor、java.lang.reflect.Field、java.lang.reflect.Method、java.lang.reflect.Modifier

反射库提供了一个非常丰富且精心设计的工具集,方便编写动态操纵java代码的程序。这项功能被大量用于javaBean中,他是java组件的体系结构。

能够分析类能力的程序称为反射

Class

一个Class对象将表示一个特定类的属性

获取Class类型对象的方法

1.      实例对象(名).getClass()。

2.      类型(名).class。

3.      Class.forName(类名路径或接口名的字符串)。无论何时,这个方法都要提供异常处理器。


Class类实际上是一个泛型类。如Employee.class的类型是Class<Employee>。

虚拟机为每个类型管理一个Class对象。因此可以用“==”运算符实现两个类对象比较。

Class类型.newInstance()调用默认构造器初始化新创建的对象。如果这个类没有默认构造器,就会抛异常。如果要使用有参构造器,必须使用Constructor类的newInstance方法。

捕获异常

API:java.lang.Throwable

异常有两种:未检查异常和已检查异常。

利用Throwable类的printStackTrace方法打印出栈的轨迹。Throwable是Exception的超类。

对于检查异常只需提供一个异常处理器。

在运行时使用反射分析对象

API:java.lang.reflect.ObjectAnalyzer

AccessibleObject是Field、Method、Constructor类的公共超类。

已知Class类对象,可以使用getDeclareFields获取所有数据域,然后使用Field类的setAccessible方法将所有域设置为可访问,这时可以用Field类的get和set方法获取每个域的值或者设置新值。

泛型toString方法查看任意对象内部信息问题:循环引用可能导致无限递归,ObjectAnalyzer将记录已经被访问的对象。例:

public String toString(){

return new ObjectAnalyzer().toString(实例对象);

}

使用反射编写泛型编写数组代码

API:java.lang.reflect.Array

如过一个User[]对象零时转成Object[]数组,然后再把它装换回来是可以的,但从一开始就是Object[]的数组却永远不能转成User[]数组。

整形数组类型int[]可以转换成Object,但不能转换成对象数组。

使用反射编写泛型数组实现方法

public static Object goodCopyOf(Object a,int newLength){

Class cl = a.getClass();//获取数组a的类对象

if(!cl.isArray()) return null;//确认a是一个数组

Class componentType = cl.getComponentType();//使用Class类的getComponentType方法确定数组的对应类型

int length = Array.getLength(a);

Object newArray = Array.newInstance(componentType, newLength);

System.arraycopy(a, 0, newArray, 0, Math.min(length, newLength));//复制

return newArray;

}

使用反射编写泛型数组实现方法

public static Object goodCopyOf(Object a,int newLength){

Class cl = a.getClass();//获取数组a的类对象

if(!cl.isArray()) return null;//确认a是一个数组

Class componentType = cl.getComponentType();//使用Class类的getComponentType方法确定数组的对应类型

int length = Array.getLength(a);

Object newArray = Array.newInstance(componentType, newLength);

System.arraycopy(a, 0, newArray, 0, Math.min(length, newLength));//复制

return newArray;

}

继承的设计技巧

1.      将公共操作和域放在超类。

2.      不要使用受保护的域。

3.      使用继承实现“is-a”关系。

4.      除非所有的方法都有意义,否则不要使用继承。

5.      在覆盖方法时,不要改变预期行为。

6.      使用多态而非类型信息。

7.      不要过多的使用反射。

接口、lambda表达式、与内部类

接口

概念

API:java.lang.Comparable<T>、java.util.Arrays

Arrays类中的sort方法可以对对象数组进行排序,但要满足一下前提:对象所属的类必须实现Comparable接口。

接口中所有的方法都属于public,因此可以省略public关键字。

接口不能含有实例域。

提供实例域和方法实现的任务应该由实现接口的那个类来完成。

接口的特性

java规范建议不写多余的关键字。

一个类可以实现多个接口。

静态方法

jse8允许在接口中添加静态方法。

默认方法

可以为接口方法提供一个默认实现(defaule修饰的方法)。

默认方法可以调用任何其他方法。

解决默认方法冲突

1.      超类优先。

2.      接口冲突。必须覆盖这个方法,或可以选择两个方法中的一个。

注意:千万不要让一个默认方法重新定义Object类中的某个方法。

接口示例

Comparator 接口(Arrays.sort的第二个版本)

一个数组和一个比较器(comparator)作为参数,比较器是实现Comparator接口类的实例。

compare方法要在比较器对象上使用,而不是在字符串本身上调用。

对象克隆

cloneable是java提供的一组标记接口。标记接口不包含任何方法,他的唯一作用是允许在类查询中使用instanceof。

即使clone的默认拷贝(浅拷贝)实现能够满足要求,还是需要实现Cloneale接口,将clone方法重新定义为public,再调用super.clone().

深拷贝中,主要是对可变变量的拷贝(除开没有更改器的常量、不可变对象外)。前提是这些不可变子对象也实现了clone。

深拷贝大致步骤

1.      实现Cloneable接口。

2.      实现类中定义clone方法,先调用父类clone,再拷贝可变子对象,返回拷贝对象。

3.      外部调用clone方法就实现深拷贝。

lambda表达式

API:java.util.function 常用函数式接口、基本类型函数式接口

lambda表达式是一个可传递的代码块,可以在以后执行一次或多次。

lambda表达式语法

(参数)-> 表达式、(参数)->{表达式}

即使lambda表达式没有参数仍要提供空括号,就像无参方法一样。

如果可以推导出一个lambda表达式的参数类型,则可忽略其参数类型。

如果方法只有一个参数,而且这个参数的参数类型可以推导的出,可省略小括号。

无需指定lambda表达式的返回类型,返回类型总是会由上下文推导得出。

如果一个lambda表达式只在某些分支返回一个值,而在另一些分支不返回值,这是不合法的。

函数式接口

对于只有一个抽象方法的接口,需要这个接口的对象时,就可以提供一个lambda表达式这种接口称为函数式接口

最好把lambda表达式看作是一个函数,而不是对象。另外lambda表达式可以传递到函数式接口。

      不能把lambda表达式赋给类型为Object的变量,Object不是一个函数式接口。

方法引用

有时可能已经有现成的方法可以完成你想要传递到其他代码的某个动作。

用::操作符分隔方法与对象类名,主要有以下3种情况:

1.      object::instanceMethod。如System.out::println等价于System.out.println(x)

2.      Class::staticMethod。如Math::pow等价于(x,y)->Math.pow(x,y)

3.      Class::instanceMethod。如String::compareToIngnoreCase等同于(x,y)->x.compareToIngnoreCase(y)

可以在方法中引用使用this参数。this::equals等同于x->this.equals(x)。使用super也是合法的,super::instanceMethod。

使用this作为目标,会调用给指定方法的超类版本。

构造器引用

利用new来使用构造器引用。如Person::new。

可以用数组类型建立构造器引用。如:int[]::new等价于x->new int[x]。

变量作用域

lambda表达式有3个部分:

1.      代码块。

2.      参数。

3.      自由变量值。

lambda表达式可以捕获外围作用域变量的值。要确保所捕获的值是明确定义的。

lambda表达式捕获的变量必须实际上是最终变量(初始化后不再赋值的变量)。

lambda表达式中声明一个与局部变量同名的参数或者局部变量是不合法的。

处理lambda表达式

使用lambda表达式的重点是延迟执行。如以下原因:

1.      在一个单独线程运行的代码。

2.      多次运行代码。

3.      在算法的适当位置运行代码。

4.      发生某种情况时运行代码。

5.      只在必要事才运行代码。

 

      如果是自己设计的接口,其中只有一个抽象方法,可以用@FunctionalInterface注解来标记这个接口。

内部类

内部类访问对象状态

内部类既可以访问自身的数据域,也可以访问创建他的外部对象的数据域。

内部类总有一个隐式引用outer,只想创建他的外部类对象。

外部类引用在构造器中设置。如内部类没有定义构造器,会默认生成一个参数含外部引用的构造器。如构造器:public Time(Talk t){

outer = t;

    }

注意:outer不是java关键字。

内部类的特殊语法规则

内部类声明的所有静态域都必须是final。

内部类不能有static方法。

表达式OuterClass.this表外围类引用。

局部内部类

局部类不能用public和private访问说明进行声明。他的作用域被限定在声明这个局部类的块中。他可以对外部世界完全的隐藏起来。

由外部发方法访问变量

局部内部类不仅能够访问包含他们的外部类,还可以访问局部变量,局部变量必须有final修饰。

匿名内部类

通常语法格式

new SuperType(construction paramters){

inner class methods and data

}

匿名类不能有构造器,而是将构造器参数传给超类构造器。尤其是在内部类实现接口的时候,不能有任何构造参数。如下:

new InterfaceType(){

method snd data

}

 

习惯用匿名内部类实现事件监听和其他回调。如今最好的做法是使用lambda表达式

匿名内部类对于equals的方法使用要当心。

new Object(){}.getClass().getEnclosingClass() //get class of static method

静态内部类

1.      在内部类不需要访问外围类对象的时候,应该使用静态内部类。

2.      静态类可以有静态域和方法。

3.      声明在接口中的内部类自动成为static和public类。



如果你喜欢我的内容,就请打赏一下吧
微信
支付宝
温馨提示: 你的打赏金额会直接转入对方账户,不可退回。

评论专区


审核通过的评论(0)
暂无评论信息
个人名片

  欢迎来到“浩瀚星尘”的个人博客!
  首先,该博客用于分享本人的生活事迹与兴趣爱好; 此外,该博客的主要作用便是与广大的小伙伴一起分享探讨开发技术, 希望大家多多关照。

网名: 浩瀚星尘
城市: 重庆
工作: java