基本操作:
施工方法
File(String pathname) 将给定的路径名字符串转换为抽象路径名以创建File 实例
示例: new File("D:java/testDoc/test.java") //文件路径
new File("D:java/testDoc") //文件夹路径
File(Stringparent, Stringchild) 根据父路径字符串和子路径字符串创建一个File 实例。
示例:new File("D:java","/testDoc/test.java") //文件
示例:new File("D:java","/testDoc") //创建文件夹
创建文件夹
mkdir(): 创建文件夹
mkdirs():创建多级文件夹并创建文件
createNewFile():创建文件重命名
renameTo(): 确定如何重命名文件或文件夹
contains(): 判断该路径是否存在
isFile(): 判断是否是文件
isDirectory(): 判断是否获取文件夹
getAbsolutePath(): 获取绝对路径,包括根路径
getName(): 获取相对路径(文件名或文件夹名)。不包括根路径
length(): 获取文件的大小,单位为字节删除
delete(): 删除文件
deleteOnExit(): 程序退出时删除文件示例代码:
//创建一个File实例对象,路径的抽象表示
文件file=new File("D:java/testDoc/test.java");
//文件file=new File("D:java/testDoc");
//文件file=new File("D:java","testDoc/test.java");
//判断路径是否存在
if (!file.exists()){
//判断是否为文件路径
if (file.isFile()){
//创建文件
文件.createNewFile();
}
//判断是否是文件夹路径
if (file.isDirectory()){
//创建文件夹
文件.mkdir();
}
}
//获取绝对路径
System.out.println(file.getAbsoluteFile()); //输出/D:java/testDoc/test.java
//获取相对路径(文件名或文件夹名)
System.out.println(file.getName()); //输出test.java
File类的高级获取
方法:listFiles() : 返回一个File数组,包含该路径名下的所有文件和文件夹路径名
listRoots(): 此方法是静态的,返回路径名下的所有根路径。
listFiles(FileFilter filter): 返回File数组,通过过滤器FileFilter进行过滤
FileFilter重写方法:accept(Filepathname)返回true表示需要包含在数组中,不要删除示例代码1:
if (文件!=null file.isDirectory()) {
//打印文件夹
System.out.println(文件);
//列出所有文件和文件夹路径
File[] 文件=file.listFiles();
for (文件f : 个文件) {
//递归调用查找所有文件和文件夹
测试文件搜索(f);
}
} 别的{
//打印文件
System.out.println(文件);
}示例代码2
if (文件!=null file.isDirectory()) {
File[] files=file.listFiles(new FileFilter() {
@覆盖
公共布尔接受(文件文件){
//.class末尾的需要保留,不要去掉
return file.getName().endsWith(".class");
}
});
}
6.2 IO流基类
字节输入流InputStream
字节输出流OutputStream
字符输入流读取器
字符输出流Writer
特点:
四个基类都是抽象类。核心功能可以用一句话概括:读进来,写出去。输出流:将数据写入目标。
输入流:从源读取数据
所有的流都是资源对象,资源使用完后必须关闭。
字节流比较通用
IO流操作模板
1):定义源或目标源:输入流目标:输出流
2):根据源和目标创建流对象
3): 执行读/写操作
4):关闭资源
6.2.1 字节流
字节输入流InputStream
字节输出流OutputStream字节文件流
1-1.FileOutputStream
将数据写到目标文件中构造方法
FileOutputStream(File file) 创建一个文件输出流,将数据写入指定File 对象的目标文件。
FileOutputStream(String name) 创建一个文件输出流,将数据写入具有指定名称的目标文件。
FileOutputStream(String name, booleanappend)append是否将常用方法追加到源数据中
write(int b) //将指定数量的字节写入输入流
write(byte[] b,int off, int len) 将指定字节数组中从off索引开始的len个字节写入到输出流分析流对象创建
1.创建输出流对象
2、通知系统检查目标文件,如果不存在则创建。
3. 将此输出流对象与硬盘上的文件关联。示例代码:
字符串dest="d:/java/test.txt"; //输出目标文件路径
尝试{
//创建一个流对象。如果该文件不存在,则会自动创建该文件。
FileOutputStream fo=new FileOutputStream(dest);
byte[] bytes="hello".getBytes();//需要写入流的数据
fo.write(字节,2,3);
fo.close();//关闭流,释放资源,等待GC回收
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
1-2.FileInputStream
从源文件读取数据施工方法
文件输入流(字符串名称)
FileInputStream(File file) 是创建从源文件读取数据的输入流对象的常用方法。
read() 从输入流中读取下一个字节的数据,
返回值是读取的字节。如果为-1,则表示已读取。
read(byte[] b) 从输入流中读取一定数量字节的数据并将其存储到缓冲区数组b 中。
返回值是读取的字节数。如果为-1,则表示已读取示例代码:
//来源
字符串路径="d:/java/in.txt";
//根据源创建输入流对象
尝试{
FileInputStream fi=new FileInputStream(路径);
//定义一个缓冲区数组
byte[] 字节=新字节[1024 * 1024];
fi.read(字节);
int len;//记录读取了多少字节
while ((len=fi.read(bytes)) !=-1) { //不等于-1表示还有数据
System.out.println(new String(bytes, 0, len));
}
fi.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}缓冲流特点
缓冲字节流和普通字节流在使用上没有区别。为什么在效率上缓冲流效率更高更有效率?
缓冲流对象的底层带有一个8k的缓冲区。该缓冲区与我们输入流的自定义缓冲区数组无关。
缓冲流对象的缓冲区是指管道的粗细,自定义缓冲区数组是指存储读取数据的地方。
缓冲流使管道变厚,使输入和输出更加高效。
字节缓冲流
2-1.BufferedInputStream
施工方法
BufferedInputStream(InputStream in) 示例代码
FileInputStream in=new FileInputStream("d:/java/test.java");
BufferedInputStream bufin=new BufferedInputStream(in);
2-2.BufferedOutputStream
施工方法
BufferedOutputStream(OutputStream out) 示例代码
FileOutputStream out=new FileOutputStream("d:/java/test.java");
BufferedOutputStream bufOut=new BufferedOutputStream(out);对象流功能
将内存中的对象输出到文件或将文件中保存的对象输入到内存中
为什么要保存到文件?
目的是在进程之间进行数据通信
序列化和反序列化
序列化: 个内存对象写出到文件
反序列化:将文件中的对象读取到内存中
序列化对象
保存的对象需要序列化。您可以通过实现Serialized 接口来启用序列化。
实现Serialized接口需要在对象中显示声明的序列化ID;当没有显式声明时,将根据类的信息生成不同的序列化ID。由于编译器不同,可能会发生意外的反序列化。
3-1.ObjectOutputStream
ObjectOutputStream 扩展了OutputStream 实现了ObjectOutput、ObjectStreamConstants
序列化:把内存中的对象保存到硬盘中施工方法
ObjectOutputStream(OutputStream out) 创建对象写入指定OutputStream的常用方法
void writeObject(Object obj) 将对象写入流示例代码
公共类ShareData 实现可序列化{
私有静态最终长serialVersionUID=-1190188205817401171L;
}
ObjectOutputStream out=new ObjectOutputStream(new FileOutputStream("data"));
ShareData 数据=new ShareData();
out.writeObject(数据);
关闭();
3-2.ObjectInputStream
ObjectInputStream扩展InputStream实现ObjectInput、ObjectStreamConstants
反序列化:将文件中的对象读取到内存中一个程序读取另一个程序的序列化数据,实现进程通信。
构造函数
ObjectInputStream(InputStream中)常用方法
readObject() 示例代码
ObjectInputStream in=new ObjectInputStream(new FileInputStream("data"));
对象对象=in.readObject();
附寄();字节数组流
4-1.ByteArrayOutputStream
ByteArrayOutputStream 扩展OutputStream
特征
数据将被写入底层缓冲区的字节数组。随着数据的不断写入,缓冲区会自动增长。
使用场景:
当我们需要接收大量数据时,有些数据并不适合一次性接收全部。我们可以使用每次收集1小部分的形式,拿到零散的数据,再将零散的数据统一收集起来,最后统一使用。这时候我们就要用到这个ByteArrayOutputStream
构造函数
ByteArrayOutputStream()常用方法
byte[] toByteArray() //将缓冲区数组的数据放入新数组中
String toString() 使用默认字符集将缓冲区数据解码为字符串
String toString(String charsetName) 使用指定的字符集将缓冲区数据解码为字符串
void write(byte[] b, int off, int len) 将数组b 写入流示例代码
ByteArrayOutputStream byteOut=new ByteArrayOutputStream();
//模拟每次都会有一部分数据过来
//这个方法是先暂时保存分散的数据
byteOut.write(new byte[]{"a", "b", "c"});
byteOut.write(new byte[]{"d", "e", "e"});
byteOut.write(new byte[]{100, 127, 32});
byte[] bytes=byteOut.toByteArray();//使用保存的分散数据
System.out.println(new String(字节));
System.out.println(byteOut.toString());//解码后的流数据是字符串
4-2.ByteArrayIntputStream
ByteArrayInputStream extends InputStream
特征
包含一个内部缓冲区,其中包含从流中读取的字节
关闭ByteArrayInputStream 没有任何效果。关闭后仍然可以调用其方法,而不会生成IOException。
构造函数
ByteArrayInputStream(byte[] buf) 创建一个流对象并使用buf 作为其缓冲区数组示例代码
byte[] bs=new byte[]{9,98,100};//将字节数组转换为流对象
ByteArrayInputStream byteIn=new ByteArrayInputStream(bs);
字节[] buf=新字节[1024];
int 长度;
while ((len=byteIn.read(buf)) !=-1){
System.out.println(new String(buf,0,len));
}
6.2.2 字符流
字符输入流读取器
字符输出流Writer 为什么使用字符流?
使用字节流读取文件可能会出现乱码,因为字节流一次只读取一个字节,而有些数据并不是由一个字节组成的,比如汉字占用两个字节或三个字节。解析的时候不知道要用多少字节来解析,所以很容易出现乱码。
字符流工作流程
字符流底部有一个1kb的缓冲区。读和写与缓冲区有关。
字符输入流:的缓冲区的作用是读取数据后用来解析数据。如果解析成功,则保存到buffer数组中;如果解析失败,则会读取另一条数据一起解析;如果要解析的字节是编码表中没有找到对应的,就会转成问号!
字符输出流:的缓冲函数首先将数据写入缓冲区,然后调用flush()方法将缓冲区数组中的数据写入文件,否则缓冲区数组满了就会被写出。
1-1. FileReader
FileReader 扩展了InputStreamReader
擅长从文件读取字符的类施工方法
FileReader(String fileName)常用方法
int read() 一次读取一个字符
int read(char[] cbuf) 将字符读入缓冲区数组示例代码
字符串路径="d:/java/test.txt";
尝试{
FileReader fr=new FileReader(路径);
char[] chrs=new char[3];//读入缓冲区数组中的字符数
int len;//记录读取了多少个字符
while ((len=fr.read(chrs)) !=-1) {
String s=new String(chrs, 0, len);
System.out.println(s);
}
fr.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
1-2.FileWriter
FileWriter 扩展OutputStreamWriter
擅长写出字符到文件的类施工方法
FileWriter(String fileName)常用方法
void write(String str) 将字符串写入文件
lush() 将缓冲的数据写出到文件中。关闭流之前调用的注意事项。
字符流的底部有一个缓冲区数组。当调用write方法时,数据会被暂时保存在buffer数组中。当缓冲区数组满时,数组中的数据会自动写入文件。我们可以手动调用flush()方法,刷新缓存区域,让数据写入文件
示例代码
字符串dest="d:/java/write.txt";
尝试{
FileWriter fw=new FileWriter(dest);
字符串needData="hossss";
fw.write(需要数据);
//刷新数据
fw.flush();
fw.close();
} catch (IOException e) {
e.printStackTrace();
}
转换字符流
功能:
为什么我们需要将字节流转换为字符流?
字节流是一种基本流。一般流对象被设计为字节流,比较通用。
有时流对象不是我们自己创建的,而是从其他地方返回的,而返回的通常是字节流。如果使用字节流来处理文本数据,可能会出现乱码,所以必须将字节流转换为字符流。
2-1.InputStreamReader
转换输入流
构造函数
输入流读取器(输入流中)
InputStreamReader(InputStream in, String charsetName) 指定字符集读取字节并解码为字符示例代码
FileInputStream in=new FileInputStream("d:/java/test.java");
InputStreamReader reader=new InputStreamReader(in, "UTF-8");
char[] chars=new char[1024];
int 长度;
while ((len=reader.read(chars)) !=-1){
System.out.println(new String(chars,0,len));
}
reader.close();
2-2.OutputStreamWriter
转换输出流
构造函数
OutputStreamWriter(输出流输出)
OutputStreamWriter(OutputStream out, String charsetName) 指定将字符编码为字节并将其写入流的字符集。示例代码
FileOutputStream out=new FileOutputStream("d:/java/test.java");
OutputStreamWriter writer=new OutputStreamWriter(out,"UTF-8");
writer.write("你好");
writer.close();//转换流的关闭包括刷新数据和关闭资源操作字符缓冲流
3-1.BufferedReader
构造方法
BufferedReader(Reader in)独特的方法
String readLine() 读取一行文本示例代码
BufferedReader 阅读器=new BufferedReader(new FileReader("d:/java
/test2.java")); String data; //记录读取到的内容 while ((data = reader.readLine()) != null){ System.out.println(data); } reader.close();3-2.BufferedWriter
构造方法 BufferedWriter(Writer out)特有方法 void newLine() 写入一个行分隔符(换行)示例代码 BufferedWriter writer = new BufferedWriter(new FileWriter("d:/java/test.java")); writer.write("哈哈"); writer.newLine();//换行 writer.write("我是哈哈"); writer.flush(); writer.close();6.3 文件拷贝
字节流拷贝 字节流可以读写文本文件和二进制文件 //需求:将test1.java的内容拷贝到test2.java FileInputStream in = new FileInputStream("d:/java/test1.java"); FileOutputStream out = new FileOutputStream("d:/java/test2.java"); byte[] bytes = new byte[1024]; int len; while ((len = in.read(bytes)) != -1) { //将读取到的数据写出去,边读边写 out.write(bytes, 0, len); } in.close(); out.close();字符流拷贝字符流只能拷贝纯文本文件,拷贝二进制文件肯定是打不开的 拷贝二进制文件的问题: 读取回来的字节数据在转换成字符的过程中,发现找不到对应的字符和它对应,而转成了?(63)只有一个字节,所以写出去的就丢失了字节,最终导致拷贝的数据变少了 //需求:将test1.java的内容拷贝到test2.java FileReader reader = new FileReader("d:/java/test1.java"); FileWriter writer = new FileWriter("d:/java/test2.java"); char[] chars = new char[1024]; int len; while ((len = reader.read(chars)) != -1) { writer.write(chars, 0, len); writer.flush(); } reader.close(); writer.close();6.4 IO流异常处理
异常处理的核心: 所有的编译时期异常必须try-catch 保证流对象得到关闭 异常一般处理示例代码 FileReader reader = null; FileWriter writer = null; try { reader = new FileReader("d:/java/test1.java"); writer = new FileWriter("d:/java/test2.java"); //需求:将test1.java的内容拷贝到test2.java char[] chars = new char[1024]; int len; while ((len = reader.read(chars)) != -1) { writer.write(chars, 0, len); writer.flush(); } } catch (Exception e) { e.printStackTrace(); }finally { if (reader != null){ try { reader.close(); } catch (Exception e) { e.printStackTrace(); }finally { if (writer != null){ try { writer.close(); } catch (Exception e) { e.printStackTrace(); } } } } }从上面的代码可以看出处理异常的代码逻辑比IO操作还多,结构嵌套很深 异常高级处理 try-with-resource java1.7开始出现的跟资源有关的 相关的对象需要实现AutoCloseable接口,流对象都实现了此接口 应用了此语法的流对象不用关闭资源,会自动关闭 这个语法只能在Java7或者更高的版本使用 语法 try ( ... 创建AutoCloseable对象的代码 ... ) { 可能出现异常的代码 } catch (异常类型 变量名) { }示例代码 try ( //创建资源对象的代码放在这里 FileReader reader = new FileReader("d:/java/test1.java"); FileWriter writer = new FileWriter("d:/java/test2.java"); ) { char[] chars = new char[1024]; int len; while ((len = reader.read(chars)) != -1) { writer.write(chars, 0, len); writer.flush(); } //不用关闭资源 //reader.close(); //writer.close(); } catch (Exception e) { e.printStackTrace(); }6.5 字符的编码和解码
编码表 所谓编码表就是用一个整数去对应一个字符 如: ASCII编码表字符"s" s -->10 -->0000 1010(二进制) ASCII- 是用**一个 8 位的字节**来表示空格、标点符号、数字、大小写字母或者控制字符的,其中最高位为 "0",其他位可以自由组合成 128 个字符的码表 - **ASCII的汉字是1个字节** - IOS-8859-1 是国际标准化组织 ISO 字符编码标准 ISO-8859 的一部分,它在 ASCII 编码空置的 0xA0-0xFF 的范围内加入了其他符号字母以供西欧来使用,所以也叫 "西欧语言",另外 ISO 的编码还有其他的一些语言编码,这些都是**单字节 8 位编码**。 - GB* - GB2312 共收录了七千个字符,由于 GB2312 支持的汉字太少而且不支持繁体中文,所以 GBK 对 GB2312 进行了扩展,对低字节不再做大于 127 的规定,以支持繁体中文和更多的字符,GBK 共支持大概 22000 个字符,GB18030 是在 GBK 的基础上又增加了藏文、蒙文、维吾尔文等主要的少数民族文字。 - **GBK的汉字是2个字节** - Unicode - 一个全球性的编码方案把所有字母和符号都统一编码进去 - UTF-8以字节为单位对Unicode进行编码 - **UTF-8的汉字是3个字节**编码和解码 编码和解码都必须依靠一个工具作为桥梁,这个工具就是编码表 编码: 把字符变成字节(整数) String类的编码方法: byte[] getBytes() 使用平台默认字符集(一般默认GBK)将String编码为byte,并存到byte数组中 byte[] getBytes(String charsetName) 使用指定字符集将String编码为byte,并存到byte数组中解码: 把字节(整数)变成字符 String类的解码方法: String(byte[] bytes) 使用默认字符集将字节数组解码成一个String对象 String(byte[] bytes,String charsetName) 使用指定字符集将字节数组解码成一个String对象编码和解码的字符集必须一致,不然在多个字节的数据中,会出现乱码 示例代码 String str = "你好啊"; byte[] bytes = str.getBytes();//使用默认字符集GBK进行编码 String s = new String(bytes); //使用默认字符集GBK进行解码 //编码和解码的字符集必须一致 byte[] bUtf = str.getBytes("UTF-8");//使用UTF-8编码 String sUtf = new String(bUtf,"UTF-8");//使用UTF-8解码6.6 属性文件 properties
使用背景 一般来说,一些简单的改动都需要经过修改源码-编译-运行,这样拓展不强,不好维护,灵活性不够. 我们可以把一些程序中的变量提取出来,放在java代码的外部,用一个文件保存,这个文件是不需要编译的,在程序运行的时候再去动态的读取这些变量信息. 实际应用 在项目中使用属性文件,文件必须以.properties结尾,在程序运行时用流去读取信息,Java中专门去读取属性文件并解析的类Properties Properties Properties extends Hashtable Properties 可以从流中加载数据或者将数据保存在流中,属性列表中的键值都是字符串 构造方法 Properties()常用方法 void load(Reader reader) 从输入字符流中读取属性键值对 String getProperty(String key) 获得指定键的属性值属性文件的写法 src=e:/qq.exe dest=d:/java/test.java示例代码 Properties properties = new Properties(); FileReader reader =new FileReader("local.properties"); //从流中加载属性文件 properties.load(reader); //根据属性键获得属性值 String src = properties.getProperty("src"); String dest = properties.getProperty("dest");6.7 RandomAccessFile
RandomAccessFile implements DataOutput, DataInput, Closeable 支持对随机访问文件的读取和写入 特征: 可以读也可以写 底层是byte[] 包含一个索引叫文件指针 发送读或写操作后文件指针会往前移动 构造方法 RandomAccessFile(String name, String mode) RandomAccessFile(File file, String mode) mode参数: r:表示只支持读,调用write方法会抛出异常 rw:表示支持读写操作,如文件不存在,则会尝试创建文件常用方法 long getFilePointer() 获得当前指针索引 seek(long offset) 设置指针位置示例代码 //创建读写的流对象 RandomAccessFile rw = new RandomAccessFile("d:/java/test.txt", "rw"); rw.writeInt(100); rw.writeChar(98); long index = rw.getFilePointer();//获得指针索引 //进行读操作前,需要先将指针回到开始位置,因为之前进行写操作,指针已移动至当前写的位置 rw.seek(0); int a = rw.readInt(); char c = rw.readChar(); rw.close();实际运用 可用于断点下载 操作步骤: 先获取到要下载的文件的大小使用一个随机读写文件记录下载的最新位置使用两个随机读取文件对要下载的文件进行关联,一个负责读,一个负责写每次操作都记录下文件的最新位置并且存入硬盘发送断点后,读取最新的记录,从最新的历史记录继续读取6.8 正则表达式
使用场景 使用正确的规则对字符串进行相关操作(匹配/替换/切割) 基本字符 x 字符x \ 反斜线字符字符类(多个中匹配1个) [abc] a b 或c [^abc] 任何字符,除了a,b或c [a-zA-Z] a到z,或 A到Z,两头的字母包含在内 [a-d[m-p]] a到d,或者m到p:[a-dm-p](并集) [a-z&&[def]] d,e或者f(交集)特殊意义字符(类似关键字) . 任何字符(与行结束符可能匹配也可能不匹配) d 数字:[0-9] D 非数字:[^0-9] s 空白字符:[tnx0Bfr] S 非空白字符:[^s] w 单词字符:[a-zA-Z_0-9] W 非单词字符:[^w]数量词 X? X, 一次或者一次也没有,<=1 X* X, 零次或者多次, >=0 X+ X, 一次或多次, >=1 X{n} X, 恰好n次, =n X{n,} X, 至少n次, >=n X{n,m} X, 至少n次,但不超过m次, >=n<=m字符串正则的常用方法 boolean matches(String regex) 判断此字符串是否匹配给定的正则表达式 String[] split(String regex) 根据给定的正则拆分字符串 String replaceAll(String regex,String replacement) 用指定的字符串替换所有匹配正则的内容正则中需要注意的 匹配文本中含有的正则特殊字符: \d , \[ , \{ , \S 匹配文本的一个反斜杠: \\ 匹配文本中的rn制表符时: rn示例代码 //1开头,11位数字,第二个数字必须为3 5 7 String tel = "13788888843"; String regex1 = "1[357]\d{9}"; boolean ma = tel.matches(regex1); System.out.println(ma); String exe = "png-jpg;gif-jpeg"; String regex2 = "[-;]"; String[] split = exe.split(regex2); for (String s : split) { System.out.println(s); } String str = "你个S B";【深入浅出Java编程基础教程】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
Java真是个好用的语言!
有17位网友表示赞同!
想要学编程,Java是个不错的起点。
有13位网友表示赞同!
学习java基础真的很有必要啊。
有9位网友表示赞同!
好多程序都是用Java写的,了解基础很重要。
有18位网友表示赞同!
想进软件行业?先从Java入手吧
有16位网友表示赞同!
最近想着入门Java语言,就来学习一下基础啦。
有10位网友表示赞同!
Java的语法看起来挺容易懂,感觉比较友好新手。
有20位网友表示赞同!
这篇文章肯定能让我对Java的基础有更好的了解。
有16位网友表示赞同!
之前一直听说Java不错,今天来学点基础看看
有19位网友表示赞同!
学习java基础真是一件很有挑战的事情!希望能够顺利入门。
有8位网友表示赞同!
感觉JAVA的应用场景很广啊,基础知识要牢记哦
有7位网友表示赞同!
从零开始学java,从基础开始慢慢积累经验吧。
有7位网友表示赞同!
这个标题简直我的菜!期待这篇文章能把Java的基础讲透彻!
有18位网友表示赞同!
想自己开发程序,Java是一定要学的呀~
有17位网友表示赞同!
学习java基础不仅实用,还能锻炼逻辑思维能力。
有17位网友表示赞同!
看这篇关于Java基础的文章,感觉可以为自己的编程道路添砖加瓦。
有13位网友表示赞同!
了解java基础知识真的很有必要,在未来编程之路也会派上大用场!
有18位网友表示赞同!
以后想尝试学习Java,看看能学出什么东西来!
有11位网友表示赞同!
学习Java的基本概念,是编程的第一步!
有7位网友表示赞同!