一、基础知识
1、常用的dos命令:打开控制台:win+R,然后cmd回车。
常用命令:pushd 路径 直接进入
- d: 回车 盘符切换
- dir(directory):列出当前目录下的文件以及文件夹
- cd (change directory)改变指定目录(进入指定目录)
- 回退 cd.. ;cd\
- 进入 cd 目录;cd 多级目录
- cls : (clear screen)清屏
- exit : 退出dos命令行
2、注释:用于解释说明程序的文字。
注释分类:①单行注释:格式: //注释文字
②多行注释:格式: /* 注释文字 */
③文档注释:格式:/** 注释文字 */
注释作用:解释说明程序,帮助我们调试错误。
3、常量:在程序执行的过程中,其值不可以发生改变的量。
常量分类:
- 字符串常量 用双引号括起来的内容(“HelloWorld”)
- 整数常量 所有整数(25,-25)
- 小数常量 所有小数(20.45)
- 字符常量 用单引号括起来的内容(‘a’,’A’,’0’)
- 布尔常量 较为特有,只有true和false
- 空常量 null
4、变量:在程序执行的过程中,在某个范围内其值可以发生改变的量。从本质上讲,变量其实是内存中的一小块区域。
变量定义格式:数据类型 变量名 = 初始化值;
变量定义注意事项:
①变量未赋值,不能直接使用;
②变量只在它所属的范围内有效(变量属于它所在的那对大括号);
③一行上可以定义多个变量,但是不建议。
5、数据类型:Java语言是强类型语言,对于每一种数据都定义了明确的具体数据类型,在内存中分配了不同大小的内存空间。
数据类型分类:①基本数据类型:
四类 八种 字节数 范围
整型 byte, 1字节 -128~127
short, 2 -32768~32767
int, 4 -2147483648~2147483648
long, 8 -2^63~2^63-1
浮点型 float, 4 -3.403E38~3.403E38
double, 8 -1.798E308~1.798E308
字符型 char, 2 表示一个字符,如(‘a’,‘A’,‘0’,‘家’)
布尔型 boolean 1 只有两个值true与false
注意:
整数默认是int类型,定义long类型的数据时,要在数据后面加L。
浮点数默认是double类型,定义float类型的数据时,要在数据后面加F。
②引用数据类型:类、接口、数组。
6、数据类型转换:在运算时,一般要求参与运算的数据类型必须一致。
①隐式转换:byte,short,char -- int -- long -- float -- double
取值范围小的数据类型与取值范围大的数据类型进行运算,会先将小的数据类型提升为大的,再运算。
②强制转换:格式:目标类型 变量名 = (目标类型)(被转换的数据); 不建议强制转换,因为会有精度的损失。
注意事项:如果超出了被赋值的数据类型的取值范围得到的结果会与你期望的结果不同;
二、基础知识之运算符
1、运算符:对常量和变量进行操作的符号。
表达式:用运算符连接起来的符合java语法的式子。不同类型的运算符连接起来的式子是不同的表达式。
举例:定义两个int类型的变量a,b,做加法(a + b)
运算符分类:算术运算符,赋值运算符,关系运算符,逻辑运算符,三元运算符。
2、算术运算符:
①+,-,*,/的基本使用
②取余与除法的区别:%:取余运算符。得到的是两个相除数据的余数。
/: 除法运算符。得到是两个相除数据的商。
使用场景: %:判断两个数据是否整除。
③整数的加法操作:
A、字符参与加法操作。拿字符在计算机中底层存储对应的数据值来参与运算的。
'0' 48
'a' 97
'A' 65
B、字符串参与加法操作。 这里的+其实不是加法,而是字符串连接符。
C、++、--的用法:
++,--运算符:对变量做加1或者减1的操作。
++或者--既可以放在变量的后面,也可以放在变量的前面。
单独使用的时候,++或者--无论是放在变量的前面还是后面,结果是一样的。
参与操作的时候:
如果++或者--在变量的后面,先拿变量做操作,后变量做++或者--。
如果++或者--在变量的前面,先变量做++或者--,后拿变量做操作。
3、赋值运算符:
A:基本 =
B:扩展 +=,-=,*=,/=,%=... (隐含了强制类型转换)
+=: a+=20;相当于a = (a的数据类型)(a + 20);
4、关系运算符:判断大小
内容:==,!=,>,>=,<,<=。关系运算符的结果是boolean类型,也就是要么是true,要么是false。
注意:千万不要把==写成=。
5、逻辑运算符:用于连接关系表达式或者值。
内容: &,|,^,!;&&,||
结论:特点:偶数个不改变本身。
与:& 有false则false。
或:| 有true则true。
异或:^ 相同则false,不同则true。
非:! true则false,false则true。
&&与&和||与|的区别:①&&和&的结果一样; ||和|的结果一样。
②&&具有短路效果,如果左边是false,右边不执行。&无论左边是true还是false,右边都会执行。
③||具有短路效果.左边是true,右边不执行。|是无论左边是false还是true,右边都会执行。
6、三元运算符:格式:(关系表达式)?表达式1:表达式2。
执行流程:
A:计算关系表达式的值,看是true还是false
B:如果是true,表达式1就是运算结果
如果是false,表达式2就是运算结果
7、键盘录入:为了提高程序的灵活性。
键盘录入数据的步骤:
①导包(位置放到class定义的上面):import java.util.Scanner;
②创建对象:Scanner sc = new Scanner(System.in);
③接收数据:int i = sc.nextInt()。
注意:next()和nextLine()的区别:
next()查找并返回来自此扫描器的下一个完整标记。完整标记的前后是与分隔模式匹配的输入信息,不能得到带空格的字符串。
nextLine()方法返回的是Enter键之前的所有字符,它是可以得到带空格的字符串的。
三、基础知识之控制语句
1、选择流程控制语句:
①顺序语句:按照代码的先后顺序,依次执行。
②if语句:第一种格式:if(关系表达式){语句体},适合做一种情况的判断。
第二种格式:if(关系表达式){语句体1}else{语句体2},适合做两种情况的判断。
第三种格式:if(关系表达式1){语句体1}else if(关系表达式2){语句体2}else{语句体n+1},适合做多种情况的判断。
③switch语句:在有限个条件,并且是等于的条件下,才会使用switch。
格式:switch(表达式){
case 值1:语句体1;break;
case 值2:语句体2;break;
...
default:语句体n+1;break;
}
格式解释:表达式的取值:byte,short,int,char。
JDK5以后可以是枚举;JDK7以后可以是String。
case后面跟的是要和表达式进行比较的值
语句体部分可以是一条或多条语句
break表示中断,结束的意思,可以结束switch语句
default语句表示所有情况都不匹配的时候,就执行该处的内容,和if语句的else相似。
2、循环流程控制语句:
①for循环语句:
格式:for(初始化语句;判断条件语句;控制条件语句) {循环体语句; }
②while循环语句:
基本格式:while(判断条件语句) {循环体语句;}
扩展格式:初始化语句;
while(判断条件语句) {
循环体语句;
控制条件语句;}
③do...while循环语句:
基本格式:do {循环体语句;}while((判断条件语句);
扩展格式:初始化语句;
do {
循环体语句;
控制条件语句;
} while((判断条件语句);
④三种循环语句的区别:
A、do...while至少执行一次循环体
B、for,while循环先判断条件是否成立,然后决定是否执行循环体
C、for和while的小区别:
for循环的初始化变量,在循环结束后,不可以被访问。而while循环的初始化变量,是可以被继续使用的。
如果初始化变量,后面还要继续访问,就使用while,否则,推荐使用for。
循环的使用推荐:for -- while -- do...while
3、控制循环语句:
①break:使用场景:在选择结构switch语句中;在循环语句中。作用:跳出单层循环,让循环提前结束。
②continue:使用场景:在循环语句中。作用:结束一次循环,继续下一次的循环。
③区别:break:退出循环(当前中断)
continue:退出本次循环(中断一次,继续下去)
四、基础知识之数组
1、随机数Random:作用:用于产生一个随机数。
使用步骤:
A、导包:import java.util.Random;
B、创建对象:Random r = new Random();
C、获取随机数:int number = r.nextInt(10);
产生的数据在0到10之间,包括0,不包括10。括号里面的10是可以变化的,如果是100,就是0-100之间的数据。
2、数组:数组是存储同一种数据类型多个元素的容器。数组既可以存储基本数据类型,也可以存储引用数据类型。
引用类型:类、接口、数组。 常量:空常量 null,是可以赋值给引用类型的。例:arr = null;
①定义格式:
格式1:数据类型[] 数组名;
格式2:数据类型 数组名[];
②数组初始化:Java中的数组必须先初始化,然后才能使用。所谓初始化:就是为数组中的数组元素分配内存空间,并为每个数组元素赋值。
初始化方式:A、动态初始化:只给出长度,由系统给出初始化值。
格式:数据类型[] 数组名 = new 数据类型[数组长度]; 数组长度其实就是数组中元素的个数。
B、静态初始化:给出初始化值,由系统决定长度。
格式:数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3,...};
简化格式:数据类型[] 数组名 = {元素1,元素2,元素3,...};
③数组的内存分配:
JVM内存划分:栈 存储局部变量:在方法中定义的变量,使用完毕,立即回收。
堆 存储new出来的东西:实体,对象。注意:每一个对象都有地址值,每一个对象的数据都有默认值,使用完毕后,会在垃圾回收器空闲的时候被回收。
方法区
本地方法区 (和系统相关)
寄存器 (给CPU使用)
④数组使用会出现的问题:
A、java.lang.ArrayIndexOutOfBoundsException 数组越界异常
产生原因:访问了不存在的索引元素。
B、java.lang.NullPointerException 空指针异常
产生原因:数组已经不指向堆内存的数据了,还使用数组名去访问元素。
为什么要记住这样的小问题呢?编程不仅仅是把代码写出来,还得在出现问题的时候能够快速的解决问题。
⑤二维数组:其实就是一个元素为一维数组的数组。
格式:数据类型[][] 数组名;(推荐)
数据类型 数组名[][];
数据类型[] 数组名[];
初始化:A、动态初始化:数据类型[][] 变量名 = new 数据类型[m][n];
B、静态初始化:数据类型[][] 变量名 = new 数据类型[][]{{元素…},{元素…},{元素…}};
简化版格式:数据类型[][] 变量名 = {{元素…},{元素…},{元素…}};
注意:二维数组名配合索引可以获取到每一个一维数组,每一个一维数组配合索引可以获取到数组中的元素。
五、基础知识之方法
1、方法(函数):就是完成特定功能的代码块。
定义格式:修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2…) {函数体;return 返回值;}
方法的两个明确:A、返回值类型,明确功能结果的数据类型;B、参数列表,明确有几个参数,以及参数的类型。
调用:A、有明确返回值的方法调用:
a、单独调用,没有意义;
b、输出调用,有意义,但是不够好,因为我不一定非要把结果输出;
c、赋值调用,推荐方式。
B、如果一个方法没有明确的返回值类型,java提供了void进行修饰。void修饰的方法调用:单独调用。
2、方法重载:在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数类型不同即可。
方法重载特点:与返回值类型无关,方法名相同和参数列表不同(个数和对应的类型不同);
注意:在调用时,虚拟机通过参数列表的不同来区分同名方法。
3、参数传递:形式参数:用于接收实际数据的变量;实际参数:实际参与运算的变量。
①如果方法的参数是基本数据类型:形式参数的改变不影响实际参数。
②如果方法的参数是引用数据类型:形式新书的改变直接影响实际参数(根本在于指向同一片内存空间,本质是改变相同地址值里的内容)。
六、基础知识之面向对象
1、概述:面向对象是基于面向过程的编程思想。
面向过程,其实就是面向着具体的每一个步骤和过程,把每一个步骤和过程完成,然后由这些功能方法相互调用,完成需求。
面向对象,就是不断的创建对象,使用对象,指挥对象做事情。强调的是对象,然后由对象去调用功能。
特点:A、面向过程:强调的是过程,所有事情都需要自己完成。
B、面向对象:是一种更符合我们思想习惯的思想(懒人思想,我把事情自己不做,交给别人去做),可以将复杂的事情简单化(对使用者来说简单了,对象里面还是很复杂的)将我们从执行者变成了指挥者角色发生了转换。
2、类与对象及其使用:
①类是用来描述现实世界的事物的。
②如何描述现实世界事物?
属性: 就是该事物的描述信息(事物身上的名词)
行为: 就是该事物能够做什么(事物身上的动词)
③Java中最基本的单位是类,Java中用class描述事物也是如此:
成员变量: 就是事物的属性
成员方法: 就是事物的行为
④定义类其实就是定义类的成员(成员变量和成员方法):
a:成员变量 和以前定义变量是一样的,只不过位置发生了改变。在类中,方法外。
b:成员方法 和以前定义方法是一样的,只不过把static去掉。
⑤类和对象的概念:
a:类:是一组相关的属性和行为的集合;
b:对象:是该类事物的具体体现。
3、成员变量与局部变量的区别:
A、在类中的位置不同
成员变量:类中,方法外;
局部变量:方法中或者方法声明上(形式参数)
B、在内存中的位置不同
成员变量:堆内存
局部变量:栈内存
C、生命周期不同
成员变量:随着对象的创建而存在,随着对象的消失而消失。
局部变量:随着方法的调用而存在,随着方法的调用完毕而消失。
D、初始化值的问题
成员变量:有默认值。
局部变量:没有默认值。必须先定义,赋值,最后使用。
4、封装:private关键字:
a:是一个权限修饰符。
b:可以修饰成员(成员变量和成员方法)。
c:被private修饰的成员只在本类中才能访问。
应用:A:把成员变量用private修饰;B:提供对应的getXxx()/setXxx()方法。
概述:是面向对象三大特征之一。是面向对象编程语言对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界无法直接操作和修改。
原则:将不需要对外提供的内容都隐藏起来。把属性隐藏,提供公共方法对其访问。成员变量private,提供对应的getXxx()/setXxx()方法
作用:通过方法来控制成员变量的操作,提高了代码的安全性。把代码用方法进行封装,提高了代码的复用性。
5、this关键字:
A:this:代表所在类的对象引用。
方法被哪个对象调用,this就代表那个对象。
B:什么时候使用this呢?
局部变量和成员变量重名。
如果有局部变量名和成员变量名相同,在局部使用的时候,采用的是就近的原则。
使用场景: 局部变量隐藏成员变量。
6、构造方法:主要用来给对象的数据进行初始化。
格式:方法名与类名相同;没有返回值类型,连void都没有;没有具体的返回值。
注意事项与重载:
A:如果我们没有给出构造方法,系统将会提供一个默认的无参构造方法供我们使用。
B:如果我们给出了构造方法,系统将不在提供默认的无参构造方法供我们使用。
这个时候,如果我们想使用无参构造方法,就必须自己提供。推荐:自己给无参构造方法。
C:构造方法也是可以重载的。
成员变量赋值: A:setXxx()方法;B:带参构造方法。
七、基础知识之常用API
1、概述:API(Application Programming Interface) : 应用程序编程接口。
步骤:A:打开帮助文档;B:点击显示,找到索引,看到输入框;C:你要学习什么内容,你就在框框里面输入什么内容;
D:看包;E:看类的描述;F:看构造方法;G:看成员方法。
2、Scanner类:作用:用Scanner类的方法可以完成接收键盘录入的数据。
Scanner:用于获取键盘录入的数据。(基本数据类型,字符串数据)。
public String nextLine():获取键盘录入的字符串数据。
3、String类:字符串类。由多个字符组成的一串数据;字符串其本质是一个字符数组。
1)构造方法:
String(String original):把字符串数据封装成字符串对象。
String(char[] value):把字符数组的数据封装成字符串对象。
String(char[] value, int index, int count):把字符数组中的一部分数据封装成字符串对象。
注意:字符串是一种比较特殊的引用数据类型,直接输出字符串对象输出的是该对象中的数据。
字符串的内容是存储在方法区的常量池里面的。是为了方便字符串的重复使用。
2)通过构造方法创建的字符串对象和直接赋值方式创建的字符串对象有什么区别呢?
①通过构造方法创建字符串对象是在堆内存。
②直接赋值方式创建对象是在方法区的常量池。
==:
①基本数据类型:比较的是基本数据类型的值是否相同。
②引用数据类型:比较的是引用数据类型的地址值是否相同。
equals:表示两个变量是否是对同一个对象的引用,即堆中的内容是否相同。
3)String类的判断功能:
boolean equals(Object obj):比较字符串的内容是否相同。
boolean equalsIgnoreCase(String str):比较字符串的内容是否相同,忽略大小写。
boolean startsWith(String str):判断字符串对象是否以指定的str开头。
boolean endsWith(String str):判断字符串对象是否以指定的str结尾。
4)String类的获取功能:
int length():获取字符串的长度,其实也就是字符个数。
char charAt(int index):获取指定索引处的字符。
int indexOf(String str):获取str在字符串对象中第一次出现的索引。
String substring(int start):从start开始截取字符串。
String substring(int start,int end):从start开始,到end结束截取字符串。包括start,不包括end。
5)String类的转换功能:
char[] toCharArray():把字符串转换为字符数组。
String toLowerCase():把字符串转换为小写字符串。
String toUpperCase():把字符串转换为大写字符串。
字符串的遍历:A:length()加上charAt();B:把字符串转换为字符数组,然后遍历数组。
6)String类的其它功能:
去除字符串两端空格:String trim()。
按照指定符号分割字符串:String[] split(String str)。
4、StringBuilder类:是一个可变的字符串。字符串缓冲区类。
String和StringBuilder的区别:String的内容是固定的;StringBuilder的内容是可变的。
常用方法:A:构造方法:StringBuilder()
B:成员方法:public int capacity():返回当前容量 (理论值)。
public int length():返回长度(已经存储的字符个数)。实际值。
public StringBuilder append(任意类型):添加数据,并返回自身对象。
public StringBuilder reverse():反转功能。
StringBuilder和String的相互转换:
①StringBuilder -- String:public String toString():通过toString()就可以实现把StringBuilder转成String。
②String -- StringBuilder:StringBuilder(String str):通过构造方法就可以实现把String转成StringBuilder。
八、基础知识之集合
1、对象数组:A:基本类型的数组:存储的元素为基本类型;B:对象数组:存储的元素为引用类型。
2、集合类之ArrayList:集合类的特点: 长度可变。
ArrayList<E>:大小可变数组的实现。 <E>:是一种特殊的数据类型,泛型。
怎么用呢?在出现E的地方我们使用引用数据类型替换即可。
举例:ArrayList<String>,ArrayList<Student>
构造方法:ArrayList()
3、ArrayList集合:
①ArrayList添加新元素:
public boolean add(E e):添加元素。
public void add(int index,E element):在指定的索引处添加一个元素。
②获取元素:public E get(int index):返回指定索引处的元素
③集合长度:public int size():返回集合中的元素的个数。
④删除元素:
public boolean remove(Object o):删除指定的元素,返回删除是否成功。
public E remove(int index):删除指定索引处的元素,返回被删除的元素。
⑤修改元素:public E set(int index,E element):修改指定索引处的元素,返回被修改的元素。
4、ArrayList遍历:
集合的遍历思想和数组的遍历思想相同;
循环遍历容器,依次取出里面的元素即可。
例:ArrayList<String> array = new ArrayList<String>();
array.add("deJingjou");
for(int x=0; x<array.size(); x++) {
String s = array.get(x);
System.out.println(s);
}
九、基础知识之IO流
1、IO流与FileWriter类:
①IO流概述及分类:
概述:可以把数据存储到文件;也可以从文件中读取数据。
分类:输入流,输出流
②FileWriter类使用:如果文件不存在,创建这个文件;如果文件存在,就把原来的数据全部清空。
1)FileWriter向文件中写数据:
A:FileWriter向文件中写数据操作步骤:
a:使用FileWriter流关联文件。
b:利用FileWriter的写方法写数据(创建输出流对象)。
c:利用FileWriter的刷新方法将数据从内存刷到硬盘上(调用输出流对象的写数据的方法)。
d:利用FileWriter的关流方法将释放占用的系统底层资源(释放资源)。
B:FileWriter方法:
构造方法:FileWriter(String fileName) 传入一个文件的路径
成员方法:void write(String str) 向文件中写str
void flush() 将内存中的数据刷新到文件中
void close() 关流释放系统底层资源
2)FileWriter注意事项:
相对路径:相对当前项目而言的,在项目的根目录下(a.txt)。
绝对路径:以盘符开始的路径(d:\\a.txt)。
close()和flush()方法的区别:
flush():刷新缓冲区。流对象还可以继续使用。
close():先刷新缓冲区,然后通知系统释放资源。流对象不可以再被使用了。
3)FileWriter其它写方法:
void write(String str):写一个字符串数据。
void write(String str,int index,int len):写一个字符串中的一部分数据。
void write(int ch):写一个字符数据,这里写int类型的好处是既可以写char类型的数据,也可以写char对应的int类型的值。'a',97
void write(char[] chs):写一个字符数组数据。
void write(char[] chs,int index,int len):写一个字符数组的一部分数据。
4)FileWriter写入换行以及向文本末尾追加:
如何实现数据的换行?
\n可以实现换行,但是windows系统自带的记事本打开并没有换行,这是为什么呢?因为windows识别的换行不是\n,而是\r\n
windows:\r\n。 linux:\n。mac:\r。
如何实现数据的追加写入? FileWriter(String fileName, boolean append)。
2、FileReader类:读数据--输入流--FileReader。
FileReader:FileReader(String fileName):传递文件名称。
①输入流读文件的步骤:
A:创建输入流对象。
B:调用输入流对象的读数据方法。
C:释放资源。
java.io.FileNotFoundException: de.txt (系统找不到指定的文件。)
②文件复制:
数据源:FileWriterDemo.java -- 读数据 -- FileReader
目的地:Copy.java -- 写数据 -- FileWriter
A、读一次写一次:
例://创建输入流对象
FileReader fr = new FileReader("FileWriterDemo.java");
//创建输出流对象
FileWriter fw = new FileWriter("Copy.java");
//读写数据
int ch;
while((ch=fr.read())!=-1) {
fw.write(ch);
}
//释放资源
fw.close();
fr.close();
B、利用字符数组拷贝文件
例://创建输入流对象
FileReader fr = new FileReader("FileWriterDemo.java");
//创建输出流对象
FileWriter fw = new FileWriter("Copy.java");
//读写数据
char[] chs = new char[1024];
int len;
while((len=fr.read(chs))!=-1) {
fw.write(chs, 0, len);
}
//释放资源
fw.close();
fr.close();
3、缓冲流的使用:
BufferedWriter:将文本写入字符输出流,缓冲各个字符,从而提供单个字符、数组和字符串的高效写入。
BufferedReader:从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
①缓冲流复制文本文件的两种方式:
数据源: FileWriterDemo.java -- 读数据 -- FileReader -- 高效的读数据 -- BufferedReader
目的地:Copy.java -- 写数据 -- FileWriter -- 高效的写数据 -- BufferedWriter
第一种方式:使用缓冲流不使用字符数组。
第二种方式:使用缓冲流使用字符数组。
例://创建输入缓冲流对象
BufferedReader br = new BufferedReader(new FileReader("FileWriterDemo.java"));
//创建输出缓冲流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));
//读写数据
/*
//一次读写一个字符
int ch;
while((ch=br.read())!=-1) {
bw.write(ch);
}
*/
//一次读写一个字符数组
char[] chs = new char[1024];
int len;
while((len=br.read(chs))!=-1) {
bw.write(chs,0,len);
}
//释放资源
bw.close();
br.close();
②缓冲流的特有方法使用:
BufferedWriter:void newLine():写一个换行符,这个换行符由系统决定,不同的操作系统newLine()方法使用的换行符不同
windows:\r\n ;linux:\n ;mac:\r。
BufferedReader:String readLine():一次读取一行数据,但是不读取换行符。
例:BufferedWriter bw = new BufferedWriter(new FileWriter("bw2.txt"));
for(int x=0; x<10; x++) {
bw.write("hello"+x);
//bw.write("\r\n");
bw.newLine();
bw.flush();
}
bw.close();
BufferedReader br = new BufferedReader(new FileReader("br.txt"));
String line;
while((line=br.readLine())!=null) {
System.out.println(line);
}
br.close();
③缓冲流的特有方法复制文件:
//创建输入缓冲流对象
BufferedReader br = new BufferedReader(new FileReader("FileWriterDemo.java"));
//创建输出缓冲流对象
BufferedWriter bw = new BufferedWriter(new FileWriter("Copy.java"));
//读写数据
String line;
while((line=br.readLine())!=null) {
bw.write(line);
bw.newLine();
bw.flush();
}
//释放资源
bw.close();
br.close();