Java笔记

Avril_High 2019-09-07 05:15:28
基本语法 编写Java程序时,应注意以下几点: * 大小写敏感:Java是大小写敏感的,这就意味着标识符Hello与hello是不同的。 * 源文件名:源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存(切记Java是大小写敏感的),文件名的后缀为.java。(如果文件名和类名不相同则会导致编译错误)。 一个源文件中只能有一个public类,一个源文件可以有多个非public类。 * 类名:Java的两大对象类型之一。类有abstract class 和 普通class,抽象类主要用于定义抽象的对象,比如鱼类(相对于大马哈鱼类而言),不能被实例化(class 大马哈鱼类extends 鱼类,可以被实例化)。对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,如 MyFirstJavaClass 。 - 类型转换:一个类只能继承一个父类。父类和子类的转换原则:子类对象可以直接赋值给父类(因为大马哈鱼一定是鱼),但是父类对象需要通过强制转换才能赋给子类(这样做是要使用人表明自己确切的知道这条鱼就是大马哈鱼),强制转换在编译时不会报错,但实际运行时系统会报错(比如如果发现你想把一条剑鱼强制转换成大马哈鱼,把鱼转换成大马哈鱼也不行)。同时类型转换不会改变对象本身,无论谁转谁,对象存放和调用方法,都是以初始化时的类为准。 * 接口:Java的两大对象类型之二。接口天然就是抽象的,不能被实例化。所以接口里的方法也天然是abstract的,是不可以有实现的。接口主要用于定义一种抽象的行为,比如日常生活接口(包括吃东西方法,睡觉方法);这种行为可以是跨类的,比如鱼类implements日常生活接口,动物类implements日常生活接口,实际的方法需要在实际的类中实现。接口支持多重继承(比如除了日常生活接口,还可以有日常活动接口,class 鱼类implements日常生活接口,日常活动接口)。接口初始化,只能通过实例化实现它的类。比如声明:日常生活接口 宠物的日常生活=new 鱼类。但是调用接口方法时,可以宠物的日常生活.吃东西方法,此时我们可以不关心具体是鱼还是动物调用的该方法。同时,接口对象和它的实现类对象可以互相转换,此时可以认为日常生活接口是鱼类和动物类的一种特殊的父类。 * 成员变量:类变量被声明为public static final类型时,类变量名称必须使用大写字母。 * 方法:所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。方法定义是否合法的标准,是系统编译时能知道用户想调用的是哪个方法,就是合法的,反之不合法。 - 方法的定义有两种:一种普通方法,需要指明返回类型,比如public int getA(),void 可以认为是返回类型的一种特例。另一种是什么都不返回,就是构造函数,比如public ClassA()。Java自动提供了一个默认构造方法,它把所有成员初始化为0。调用普通方法,只需要instanceClassA.getA即可;调用构造函数,则需要通过new ClassA()的方式,此时是new在起作用返回了对象的引用 。 - 方法的传参:和C++不同,Java是没有指针的,所以所有的传参都是按值传参。如果参数是基本数据类型,则传递的是值;如果参数是对象实例,则传递的是对象的地址值(因为代表对象实例这个变量里存的就是对象的内存地址值)。 - 方法的可变传参:类型... 表示声明了一个数量不确定的入参,入参必须符合两个条件:同类型,且为最后一个入参。比如String类的format方法(format(String format, Object... args) ),类的主方法main方法也可以(main(String... args))。 - 方法的重写:同一个类中,可以有同名的方法,只要入参不同。 - 方法的重载:子类如果和父类的方法完全相同(方法名,入参,返回值是父方法返回值的子类),则子类的方法覆盖父类的方法;方法名相同,入参不同,为新方法;方法名和入参相同,返回值不是父方法返回值的子类,编译报错。对应的编译时注解:@Override。 - protected void finalize方法:它不是析构方法,因为它有void返回值而且是Object的protected方法。jvm在检测到内存不可达时,会尝试自动调用finalize方法(不是释放内存,释放内存仍然由gc来自动控制和管理)。所以,一般用在使用了native的场景,因为此时需要调用C++相关的方法,这个内存回收任务gc做不到。 * 主方法入口:所有的Java 程序由public static void main(String args[])方法开始执行。args叫做命令行参数,以空格分隔。 javac Myprogram.java java Myprogram “a b” “cd”; java Myprogram a b; 基本数据类型:Java不存在无符号的数字类型。 * 整型: byte,short, int, long, * 浮点型: float, double * 字符型:char * 布尔型:boolean * 精度:精度是指能精确存储的数字多少,和小数点位数无关(比如0.0000010和1.0和10,精度都是2位)。精度丢失,同样也和位数无关(比如int2147483647,转换成float为2.14748365*e9,丢失了最后两位的精度,但是大小没怎么变)。所以整型总能转成浮点,但是浮点没办法转成整型(发生数据丢失,而不是精度丢失了)。float大概能保留8位(单)精度,double是16位。 * 转换: - 自动转换:运算符操作时会自动转换,遵循原则byte/char/short -> int ->  long -> float -> double - 强制转换:可能会导致数据的丢失。 * 编码格式:unicode是一个字符集,即为每个字符编了一个号,两字节只够编基本的65535个字符,超过的就需要更大的编号。UTF(unicode transformed format)是这个编号的存储形式,比如1这个编号,到底是存成0001还是1。UTF-16和UTF-32是定长的,而UTF-8是不定长的,后者的好处就是文件大小会显著减少。Java内部存储都是采用的unicode码(即一个字符占用2字节),char存储的就是字符,一个char占2个byte(比如“中”这个字符的unicode码是4e2d,char存的内容就是4e2d)。比较特殊的是String的getBytes方法,它返回的不是String在系统内存中的内容,而只是字符编码输出后再转成byte而已(比如getBytes(”UTF-16”)时,“中”输出的是feff4e2d,表示大端序编码方式)。因为char是基础类型,String只是个类。 修饰符 * static :修饰类、变量或者方法,main 是Myprogram中的静态方法。静态方法允许该方法在类没有实例化之前就被调用,所以我们才可以在外部直接运行main方法。因此,静态方法中不能直接访问类的非静态变量和方法,因为它运行的时候,没有实例化;而只有static定义的东西,才是类级别的,其它都需要实例化后才能访问。 * public》protected〉default》private 修饰类、变量或者方法,子类的方法权限需要大于父类的方法权限 * final:修饰类、变量或者方法,对于一个final变量,如果是基本数据类型的变量比如int,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量比如String,则在对其初始化之后便不能再让其指向另一个对象,但是对象本身的值是可变的(比如 final int[2] a={1,2};后,a[1]=3是可以的,但是a= new int(){1,2}是不可以的)。 * abstract:修饰类或方法,抽象类是对一类对象的模型进行抽象,比如鱼类会游泳,有腮,定义为一个包含腮成员和游泳方法的抽象类,其它鱼基于该抽象类实现(class 大马哈鱼 extends 鱼类)。抽象类本身不能被实例化。如果类里的方法只是打算用来统一所有继承它的子类的行为,而不打算给里面的方法写真正的代码,可以把它定义成抽象类和抽象方法,比如作为一个SE写一个基础样例类给所有开发人员继承,但是又要防止开发人员错误的直接使用这个类初始化,因为实际上这个类里只有一堆定义一行代码都没有。接口也是抽象的,但是它只能包含抽象方法,不能包含成员,也不能包含实现方法。 * transient:成员变量前,如果一个类implements Serializable,加了该修饰符的成员变量,在序列化时不会被序列化。序列化针对不的是对象,不是类,所以static修饰的成员变量,天然就是transient的。 * synchronized:修饰方法或者代码段,只对多线程场景有用。关键字声明的方法同一时间只能被一个线程访问(保证了方法的原子性),并且会在方法执行完成后将修改的变量值刷新到主内存中(等价于将该变量定义为volatile,保证了可见性)。类中方法加上该修饰符,主要用于保护我定义的这个方法,不允许同时有多个线程调用,只能依次调用。比如,我定义了一个银行类,里面有一个吐钱方法(里面会减少银行余额这个成员变量),可不能允许同时并发吐钱,所以加上synchronized保护。这样客户类这个线程类,调用银行类中的吐钱方法时,就没办法并发操作余额变量了。synchronized内部原理,实际上是系统实现了一个基于对象实例的monitor(即锁),谁要调用这个实例的方法,就需要获取到锁才能调用;调用完成后,再把这个锁释放掉。但是如果有2个实例都在操作这个变量就锁不住了(比如银行类实例化了两个对象工商银行和建设银行,那么两个银行的吐钱方法各自获取到的是工商银行的锁和建设银行的锁,如果两个银行的余额变量是放在一起的即用static定义,同样会有并发问题)。如果synchronized修饰的是static方法,那么外部线程调用这个方法时申请的就是类锁,所有实例都需要申请同一个类锁。同时,因为它是获取的对象锁,所以如果对象中定义了两个synchronized方法,运行时的时候获取的是同一把锁,同样存在竞争关系。 * volatile:修饰成员变量,只对多线程场景有用。它要求线程读和写该变量时,都必须从共享内存中刷新或者写回共享内存。但是因为它只能修饰一个变量,所以无法保证一组操作的原子性。所以一般只用在一个线程读,一个线程写的场景;不能用于同时写的场景。但是也因此,比synchronized 性能快一些。 * native:修饰方法,表明这个方法不是用Java 代码实现的,所以Java代码里也不会有它的实现体,但它不是抽象方法,它的实现体在dll或者其他符合JNI(Java native interface)可以识别的库包中。 关键字: * assert:断言的作用可以被简单的if替代,但是当程序运行时就会一直判断,消耗性能。如果程序员只打算用来调试代码,而不是用来保证程序健壮性(比如private方法的入参调试,使用断言;而public方法的入参检查就不适合用断言)。assert[boolean 表达式 : 错误表达式 (日志)] 注解: 编译时注解 运行时注解 泛型:泛型的效果是数据和动作剥离。java的泛型只是针对编译而言,对运行态来讲没有泛型(即类型擦除);jvm只在编译的时候,会把类型代入进行编译检查(因为使用泛型的时候,会把泛型替换为真正有实际意义的类型,才能检查起来),在运行的时候则忽略该类型(实际把泛型全都替换为了Object类,所以(new ArrayList<String>).getClass和(new ArrayList<Number>).getClass是获取的一个类ArrayList<Object>,同时也无法创建一个基本数据类型的泛型实例比如<int>,因为基本数据类型不是Object类的子类)。 * 泛型类:指类中需要使用一个或者多个不确定的类型(比如一个生物园类,他需要实例化的对象类型是不确定的,可能是动物园也可能是植物园),我们也可以通过定义一个Object对象利用多态来解决这个问题,但是这样对使用者来说有两个问题,一是获取到的值需要做强制类型转换(我拿到生物园实例中的一个东东,需要把它强制转换为动物或者植物才能用,有点小麻烦),二是类型不安全的(比如把植物放进了动物园对象实例,或者把动物放进了植物园对象实例,只有在运行态才能发现获取到的是植物所以不能喂食肉类抛异常),模版允许在声明的时候就声明这个生物园类里只能放动物(比如:生物园类<动物类> 上海动物园),这样后面调用时任何不是动物的东西放入时,编译就会报错,而不用等到运行时。所以泛型一般用于集合类中。想在类中使用泛型,只需要在类定义的类名后加入自己定义的泛型名称即可,比如class MyClass<MyType>,类中就可以使用这个MyType了。 * 泛型接口:也可以使用泛型,方式同泛型类。 * 泛型方法:不想定义泛型类,只想在方法中使用泛型,可以使用泛型方法。泛型名称需要加在方法名的前面,和泛型类恰好相反,如public <MyType > void myMethod ()。泛型方法主要就是让代码结构更简单。
...全文
34 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
wowpH 2019-09-07
  • 打赏
  • 举报
回复
Avril_High 2019-09-07
  • 打赏
  • 举报
回复
输入输出 IO类:IO包中绝大部分的类都是由以下四个类直接或间接继承来的 InputStream,OutputStream,Reader,Writer。他们是Object的直接抽象子类。此外还有Serializable接口类,文件类。 流:流是在数据(Java程序中可以使用的数据对象)和io设备(比如文件,内存,磁盘,控制台,网络设备)间建立的一个管道。输入和输出都是相对于Java进程而言,InputStream/Reader输入流从io设备中获取数据,OutputStream/Writer输出流将数据输出给io设备。 * 按流的数据单位分为:字节流(InputStream、OutputStream),字符流(Reader、Writer)。当操作流中的数据含有中文的时候,就必须使用字符流进行读写。 * 按流的构造函数分为节点流、处理流(过滤流)。节点流用于和特定设备直接相连,比如ByteArrayInputStream、FileInputStream等;处理流构造时需要依赖已有的节点流才能和设备相连,比如BufferedInputStream、Objectoutputstream、DataInputStream等,大部分使用场景,处理流都是和FileStream配合。 字节流 1.InputStream的方法: * close() * mark(int):调用时记录当前读取位置,后续可通过reset回到该读取位置,一般使用mark(0)。 * reset() * skip(long 希望跳过不读取的字节数) * read方法有3种: - 读取一个byte作为int返回 - 将读取的数据放入一个byte[] - 将读取指定长度的数据放入一个byte[] 2.OutputStream的方法: * close() * flush() * write方法有3种: - 输出一个byte - 输出一个byte[] - 输出一个指定长度的byte[] 3. * ByteArrayInput/outputStream:传入内部缓冲区(其实就是一个字节数组,new ByteArrayInputStream(byte buf[]) )作为构造函数入参,为什么不能直接操作数组?无需close(为什么?)。 * CharArrayReader:传入字节数组,new CharArrayReader(char[] buf, int offset, int length) * PipedInput/OutputStream:从管道中读写数据,必须成对使用,互为构造函数的入参,可以用于线程间的通信。注意read的时候,即使不限制大小,默认一次也只能读取1024个字节。 * FileInput/OutputStream :传入某个文件(String,File 或 FileDescriptor)作为构造函数入参。处理流经常使用本节点流作为入参。 * ObjectInput/OutputStream:处理流,用来读写序列化对象给对应的节点流,所以构造函数需要传参节点流对象实例。 - 类序列化:支持所有实现了Serializable接口的类(out对象实例oos.writeObject(Java对象实例s))。同时,read/writeObject支持重写,在实现的过程中,会通过反射在s中寻找writeObject(参数为ObjectOutputStream)的方法,如果找到了就会调用s.writeObject(oos)方法;没找到的话会使用默认的实现。所以,可以通过在s对象中重写该方法,来实现自己的序列化存储。 - 基本数据类型序列化:out对象实例.writeInt(1234)。 * BufferedInput/OutputStream :处理流,作用是为另一个输入流添加一些功能,例如,提供“缓冲功能”以及支持“mark()标记”和“reset()重置方法”,所以构造函数需要传入一个节点流和一个缓存大小值(不传,默认8192)。BufferedInputStream 本质上是通过一个内部缓冲区数组实现的。例如,在新建某输入流对应的BufferedInputStream后,当我们通过read()读取输入流的数据时,BufferedInputStream会将该输入流的数据分批的填入到缓冲区中。每当缓冲区中的数据被读完之后,输入流会再次填充数据缓冲区;如此反复,直到我们读完输入流数据位置。 * DataInput/OutputStream:处理流,作用和ObjectStream类似,但不能直接存储对象,只能存储某个基本数据类型的成员变量(采用UTF-8),所以也没有要求序列化的约束条件。 * PrintStream:处理流,唯一一个孤立的Outputstream。作用为为其他输出流添加使它们能够方便地打印各种数据值的功能,所以主要提供了很多print,println数据方法。 * 举例:System.out实际就是一个PrintStream对象实例。 第1步 FileDescriptor fd = FileDescriptor.out; 第2步 FileOutputStream fdOut = new FileOutputStream(fd); 第3步 BufferedOutputStream bufOut = new BufferedOutputStream(fdOut, 128); 第4步 PrintStream ps = new PrintStream(bufout, true); 第5步 setOut0(ps); 字符流 序列化: * Serializable:接口,用于保存Java对象,比如程序停止的时候需要保存一些对象的状态到文件(序列化),当下次启动时再把它们加载回来(反序列化)。也可以用于网络间对象的传输,只要传输的两头对这个对象定义的结构相同。这个接口本身不需要实现者做任何代码开发,JVM已经实现了相关功能(打开保存的序列化文件,看到的也是一堆乱码)。但只能保存不含动态资源(Thread类,Socket类对象,编译会出错)的实例化对象(不保存static变量)的成员变量信息(不保存方法相关的信息),同时transient变量也不会被保存下来。 -serialVersionUID 是用于记录class文件的版本信息的,serialVersionUID这个数字是通过一个类的类名、成员、包名、工程名算出的一个数字,也可以自己编号维护。 * Externalizable: 文件类:对文件类的读写,都依赖FileInput/OutputStream。 * File类:提供文件或者目录的增删查功能。实现了Serializable接口和Comparable接口。实现Serializable接口,意味着File对象支持序列化操作。而实现Comparable接口,意味着File对象之间可以比较大小;File能直接被存储在有序集合(如TreeSet、TreeMap中)。 * Filedescriptor类:为文件的读写功能提供了基础,存放文件或者套接字信息(对于Linux来说,一切皆文件,当应用程序打开一个文件或者建立一个socket连接的时候,内核返回给应用程序一个非负的整数,使用这个称之为filedescriptor的东西来实现对文件或者socket的操作。),是真正代表了操作系统文件对象的东东。通过FileInputStream的getfd方法,可以获得File对应的Filedescriptor。 它有3个static成员变量,(0) in -- 标准输入(键盘)的描述符,(1) out -- 标准输出(屏幕)的描述符,(2) err -- 标准错误输出(屏幕)的描述符。
Avril_High 2019-09-07
  • 打赏
  • 举报
回复
运算符:运算符由Java提供,不支持重载(即运算符提供了什么能力,就只能用什么能力)。除了=,==和!=外,其他操作符都只能操作基本数据类型(包装类通过自动拆装箱也能完成运算)。优先级基本上从高到低。 * 算术运算符:+ - * / % ++ — - + 有个特例,String类不是数据类型但可以使用+,这实际上不是运算符的重载,而是Java提供了一个语法糖(看上去是+,实际编译时就被替换成了StringBuffer.append)。 * 关系运算符:== != > < - ==对于基本数据类型,比较值;对于对象,比较内存地址。所以一般类比较使用的是equals方法(Object类中提供了默认equal方法,基于==实现)。 * 位运算符:>> >>>  <<  & ^ | ~ * 逻辑运算符:&& || ! * 赋值运算符: = += -= * 三元运算符: variable x = (expression) ? value if true : value if false * instanceof: 对象实例 instanceof 类名/接口名 包装类:基本数据类型是没有面向对象的特点的,包装类把基本数据类型包装成了对象,使得使用起来和其他普通类没有什么区别(比如Integer a=new Integer(1))。 - 装箱:把基本类型赋值给包装类的动作叫装箱(Integer num3 = 3),装箱是系统自动完成的。装箱和new有一些区别,new一定会生成一个新的对象,装箱则不一定(对所有整型包装类,Java都实现了常量池技术,会把一些常用的int数字-128~127先事先生成好Integer对象放在内存的方法区里,装箱时就把这个生成好的对象返回给变量,所以有可能出现两个对象变量指向的是同一对象)。 - 拆箱:反之为拆箱(int num4 = num3)。包装类里都有形为××Value()(比如num3.intValue())的方法,效果类似。 * Number类型:所有的数据包装类(Byte、Short、Integer、Long、Float、Double)都是抽象类Number的子类。 - byte/Byte 1 byte(8 bit) 存储字节数据(使用较多) - short/Short 2 byte(16 bit) 兼容性考虑(使用较少) - int/Integer 4 byte(32 bit) 存储普通整数(非常常用) - long/Long 8 byte(64 bit) 存储长整型(常用) - float/Float 存储浮点数(使用较少) - double/Double 存储双精度数(使用较多) * Boolean类 @boolean/Boolean 1 byte(8 bit ) 存储逻辑变量(非常常用) * Character类 char/Character 2 byte(64 bit) 存储字符数据(使用较多) 字符串类:三种字符串类,实际上都是对char[]的封装类,实现了CharSequence接口,只是使用场景不同。 * String类:是final修饰的类,并且类里的三个关键成员变量也都是final修饰的,而且也没有提供公共的set方法,所以String对象一旦产生,就无法被更改,这主要是出于安全考虑(比如其它人有可能调用set方法,修改存放的url、密码等关键信息。)。调用String a=“abc”;效果和a=new Sting(“abc”);都是new了一个新的对象给引用变量,而不是修改原有对象(差别是前者因为常量池技术所以存在jvm内存的方法区,后者存在堆中);所以,每个String的方法都是有返回值的,返回一个新的String。如果频繁修改,可能会占用较大的内存。 - valueOf(基本数据类型):一个特殊的静态方法,用于转换基本数据类型为String。神奇的是,包装类也有这个静态方法,用来把String转换成包装类。 - Object对象实例.toString():toString是Object的方法,所以任何类对象都可以用它转换成String。 * StringBuilder类:没有final修饰,对象可变。需要通过new来初始化。 * StringBuffer类:可以认为是线程安全的StringBuilder。 日期和时间类: * util.Date类:已弃用。需要联合DateFormat才能初始化一个对象出来。 如下三个sql类均继承继承util.Date。 * sql.Date类: * sql.Time类: * sql.Timestamp类: * Calendar类:util.Date的替代方案。不能直接初始化,需要通过静态方法getInstance()获取实例化的对象。 正则表达式java.util.regex包: * Pattern类:pattern对象没有公共构造函数,只能通过一个静态方法返回类实例(Pattern.compile(”String类的正则表达式字符串”))。 * Matcher类:Matcher对象执行匹配字符串的操作,没有公共构造方法,只能通过调用Pattern对象的matcher方法来获得(Matcher对象实例=Pattern对象实例.matcher(“任何CharSequence类的待匹配字符串”))。 * PatternSyntaxException:PatternSyntaxException是一个非强制异常类,它表示一个正则表达式模式中的语法错误。 * 匹配方式:正则表达式一般为前瞻匹配,即每检查到一个字符,都先检查一下其后的字符是否符合表达式的第一部分匹配模式,不符合则再往后移动一位(如果加了^,则只有第一个字符开始满足要求才行,不会往后移动了,因为后面的都不符合^这个表达式了),直到匹配到为止。匹配到后,则采用上述模式,继续匹配表达式的第二部分,直到全部匹配整个表达式,则找到匹配字符串。 - 匹配字符集:【.】表示换行以外的字符,【[^abc]】表示abc以外的字符,【\某个字符】有特殊含义比如数字(\d)非数字(\D)。 - 匹配次数:【.*】是匹配所有字符,字符出现n次;【[^abc]*】是匹配所有abc以外的字符,字符出现n次。 - 转义:正则中有特殊含义的字符,如果想匹配,则需要转义(【\.】匹配字符.)。 - 匹配不存在某个字符串的内容:【(?!字符串)】。 - 或:正则中没有与,只有或【|】。 - 分组: 异常Exception类: * 检查型/强制异常(CheckedException):在Java中所有不是RuntimeException派生的Exception都是检查型异常。当函数中存在抛出检查型异常的操作时该函数的函数声明中必须包含throws语句。调用改函数的函数也必须对该异常进行处理,如不进行处理则必须在调用函数上声明throws语句。在JDK代码中大量的异常属于检查型异常,包括IOException,SQLException等等。 * 非检查型/非强制异常(UncheckedException):在Java中所有RuntimeException的派生类都是非检查型异常,与检查型异常对比,非检查型异常可以不在函数声明中添加throws语句,调用函数上也不需要强制处理。常见的NullPointException,ClassCastException是常见的非检查型异常。非检查型异常可以不使用try...catch进行处理,但是如果有异常产生,则异常将由JVM进行处理。对于RuntimeException的子类最好也使用异常处理机制。虽然RuntimeException的异常可以不使用try...catch进行处理,但是如果一旦发生异常,则肯定会导致程序中断执行,所以,为了保证程序再出错后依然可以执行,在开发代码时最好使用try...catch的异常处理机制进行处理。 * 异常处理: * finally 静态数组类:即我们通常意义上说的数组,是最特殊的Java类,Object的直接子类,但是没有类文件,也没有构造函数。它的大小一旦初始化后就不能变化了。 * 声明:int[] intarray或int intarray[]。 * 初始化:new int[3];intarray ={1,2,3};或者new int[]{3, 1, 2, 6, 4, 2} * 工具类:java.util.Arrays类提供了一系列的静态方法,以数组对象实例作为入参。 动态数组类:比较常见的是ArrayList

51,412

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧