一、基础知识
1、JVM、JRE和JDK的区别
JVM:java虚拟机,用于保证java的跨平台的特性。
java语言是跨平台,jvm不是跨平台的。
JRE:java的运行环境,包括jvm+java的核心类库。
JDK:java的开发工具,包括jre+开发工具
2、Java体系
1、javaSE,标准版,各应用平台的基础,桌面开发和低端商务应用的解决方案。
2、javaEE,企业版,以企业为环境而开发应用程序的解决方案。
3、javaME,微型版,致力于消费产品和嵌入式设备的最佳方案。
3、环境变量path和classpath
(1)path是配置Windows可执行文件的搜索路径,即扩展名为.exe的程序文件所在的目录,
用于指定DOS窗口命令的路径。
(2)Classpath是配置class文件所在的目录,用于指定类搜索路径,JVM就是通过它来寻找该类的class类文件的。
4、Java的编写、编译与运行
Java程序非常重要的两个阶段:编译阶段 运行阶段
源代码不能直接执行,需要先进行编译,生成源代码对应的“字节码”,JVM可以识别的是字节码。
.java文件就是源文件,这个文件中编写源代码。
.class文件就是字节码文件,这个文件是编译源代码而得到的。
1个Java源文件是可以编译生成多个class文件的,而最终运行的是class文件。
而程序员需要做的就是:
**编写--->编译--->运行**
5、变量
答:变量的作用:用来存储数据。
为什么要定义变量:用来不断的存放同一类型的常量,并可以重复使用
变量由 数据类型、变量名和变量值三部分组成。变量在使用前必须定义,包括变量的声明和赋值
6、标示符命名规则
1)、名称只能由字母、数字、下划线、$符号组成
2)、不能以数字开头
3)、名称不能使用JAVA中的关键字。
4)、坚决不允许出现中文及拼音命名。
二、数据类型
1、数据类型
(1)基本数据类型(4类8种):
整数类型:byte、short、int、long
浮点数类型:float、double
字符类型:char
布尔类型:boolean(ture false)
(2)引用数据类型:
类 接口 数组 枚举
2、数据类型转换
(1)自动(隐式)类型转换
隐式转换也叫作自动类型转换, 由系统自动完成.
从存储范围小的类型到存储范围大的类型.
byte ->short(char)->int->long->float->double
例如:
double i = 100 ; //100字面量为int类型,自动转换为double类型
(2)强制(显式)类型转换
显示类型转换也叫作强制类型转换, 是从存储范围大的类型到存储范围小的类型.
当我们需要将数值范围较大的数值类型赋给数值范围较小的数值类型变量时,此时可能会丢失精度
double→float→long→int→short(char)→byte
例如:
int i = (int)23745656L; //23745656L字面量为long类型,强制转换为int类型
要注意的是:
byte num = 20 ;
//在该语句执行时,20虽然字面量是一个int类型的常量,但是由于Java语言中进行了专门定义,
//如果所赋值数据在byte类型存储范围内,将实现自动转换,而在超过byte的存储范围的时候才会需要进行强制转换
3、方法
定义:方法就是定义在类中的具有特定功能的一段独立小程序。
特点:
定义方法可以将功能代码进行封装
便于对该功能进行复用
方法只有被调用才会被执行
方法的出现提高了代码的复用性
4、转义字符
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9oXery4d-1625134659550)(https://i.loli.net/2021/06/29/SBmlKazCQOf9Xqs.png)]
5、数组
概念:同一种数据类型的集合。
好处:可以自动给数组中的元素从0开始编号,方便操作这些元素。
三、面向对象
1、面向对象思想
(1)概述:面向对象是相对于面向过程而言的,面向过程强调的是功能,面向对象强调的是将功能封装进对象,
强调具备功能的对象;
把现实世界中的对象抽象地体现在编程世界中,一个对象代表了某个具体的操作。一个个对象最终组成了完整的程序设计,这些对象可以是独立存在的,也可以是从别的对象继承过来的。对象之间通过相互作用传递信息,实现程序开发。
现实世界的所有事物全都被视为对象。OOP的目标是在计算机程序中,模拟现实世界中的概念,我们可以借助对象的描述就能够在计算机程序中用类似的实体模拟现实世界中的实体。同时OOP也是设计和实现软件系统的方法。
(2)思想特点:
A:是符合人们思考习惯的一种思想;
B:将复杂的事情简单化了;
C:将程序员从执行者变成了指挥者;
(3)特征:
封装:隐藏对象的属性和实现细节,仅对外提供公共访问方式
继承: 多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义,这些属性和行为,只要继承那个类即可。
多态: 一个对象在程序不同运行时刻代表的多种状态,父类或者接口的引用指向子类对象
优势:易维护 可重用 可扩展
2、类和对象
类:对现实世界中某类事物的描述,是抽象的,概念上的定义。
对象:事物具体存在的个体。
类是客观世界的抽象,对象是具体的实例。
1、对象:看得见摸得着的具体事物。 类:抽象化的概念
2、类和对象的关系:
类是对象的模板/抽象化的概念,对象是类的实例。
3、创建类和对象
类: 特征:全局变量/属性/成员变量
动作:方法
成员属性(Field),主要用于保存对象的具体特征。例如:不同的人都有姓名、性别、学历、身高、体重等信息,但是不同的人都有不同的内容定义,而类就需要对这些描述信息进行统一的管理;
方法(Method),用于描述功能,例如:跑步、吃饭、唱歌,所有人的对象都有相同的功能。
对象: 类名 对象名=new 类名()
注意:一个类可以创建多个对象,,每个对象之间没有关系。
对象实例化格式:
声明并实例化对象:类名称 对象名称 = new 类名称 () ;
分步定义:
声明对象:类名称 对象名称 = null ;
实例化对象:对象名称 = new 类名称 () ;
对象调用类结构:
对象.成员属性:表示调用类之中的成员属性,可以为其赋值或者获取其保存内容
对象.方法():表示调用类之中的方法。
3、构造方法
构造方法的作用: 1.创建对象
2.在调用构造方法的时候完成对实例变量的初始化
1 当一个类中没有提供任何构造方法,系统默认提供一个无参数的构造方法。
这个无参数的构造方法叫做缺省构造器。
2 当一个类中手动的提供了构造方法,那么系统将不再默认提供无参数构造方法。
建议将无参数构造方法手动的写出来,这样一定不会出问题。
3 无参数构造方法和有参数的构造方法都可以调用。
Student x = new Student();
Student y = new Student(123);
4 构造方法是支持方法重载
在一个类当中构造方法可以有多个。
并且所有的构造方法名字都是一样的。
5 对于实例变量来说,只要你在构造方法中没有手动给它赋值,
统一都会默认赋值。默认赋系统值。
而默认赋值,是在调用构造方法实例化的时候赋值,也就是new的时候赋值
注意: 构造方法名与类名必须保持一致。比如类名为Bird,构造方法为public bird(){}
构造方法没有返回值,不需要制定返回值类型,也不能写void
4、static关键字
static是一个用于声明程序结构的关键字,利用此关键字可以用于全局属性和全局方法的声明,
主要的特点是可以避免对象实例化的限制,可以在没有实例化对象的时候直接进行此类结构的访问。
4.1 static属性
类中的每个实例化对象都应该有各自对应的属性(不同对象的属性保存在不同的堆内存中),而如果想要类中的某个属性定义为公共属性(所有对象都可以使用,并且所有对象的该属性内容应该是一样的),这个时候就可以在声明属性前加上static关键字。
范例:
class Chinese {
private String name ;// 【普通成员属性】保存姓名信息
private int age ;// 【普通成员属性】保存年龄信息
static String country = "中华人民共和国" ; // 【静态成员属性】国家,暂时不封装
public Chinese(String name,int age) {// 设置普通属性内容
this.name = name ;// 设置name属性内容
this.age = age ; // 设置age属性内容
}
// setter、getter略
public String getInfo() {
return "姓名:" + this.name + "、年龄:" + this.age + "、国家:" + this.country ;
}
}
public class JavaDemo {
public static void main(String args[]) {
Chinese perA = new Chinese("张三",10) ;// 实例化Chinese类对象
Chinese perB = new Chinese("李四",10) ;// 实例化Chinese类对象
Chinese perC = new Chinese("王五",11) ;// 实例化Chinese类对象
perA.country = "伟大的中国" ; // 修改静态属性内容
System.out.println(perA.getInfo()) ;// 获取对象信息
System.out.println(perB.getInfo()) ;// 获取对象信息
System.out.println(perC.getInfo()) ;// 获取对象信息
}
}
其内存图应该如图:
由内存图可知,通过static关键字定义的country属性是公共属性,保存在全局数据区,所有对象都可以获取该内容,如果一个对象修改了static属性内容,那么将会影响到其他所有对象的该属性内容,所有对象的该属性内容都会发生改变。
此外:我们知道使用static定义的属性表示类属性(即公共属性),类属性可以由类名称直接进行调用并且可以在没有进行实例化的时候就进行定义。(类属性也可以通过实例化对象进行调用,但是容易与普通成员属性混淆,因此不提倡使用)。
4.2 static定义方法
同样,使用static定义的方法可以在没有实例化对象的情况下进行方法的调用。
范例:
class Chinese {
private String name ; // 【普通成员属性】保存姓名信息
private int age ; // 【普通成员属性】保存年龄信息
private static String country = "中国" ; // 【静态成员属性】保存国家信息
public Chinese(String name,int age) { // 设置普通属性内容
this.name = name ; // 设置name属性内容
this.age = age ; // 设置age属性内容
}
public static void setCountry(String c) {
country = c;// 修改static属性
}
// setter、getter略
public String getInfo() {
return "姓名:" + this.name + "、年龄:" + this.age + "、国家:" + Chinese.country ;
}
}
public class JavaDemo {
public static void main(String args[]) {
Chinese.setCountry("中华人民共和国") ; // 修改静态属性内容
Chinese per = new Chinese("张三",10) ; // 实例化Chinese类对象
System.out.println(per.getInfo()) ;// 获取对象信息
}
}
本程序对静态属性country进行封装处理,这样类的外部就无法直接进行此属性的调用,因此我们就需要设置一个类似于setter方法功能的static方法setCountry(),这样static定义的方法和属性均不受到实例化对象的限制,这就可以直接利用类名称进行static方法的定义。
名称 | 调用实例方法 | 访问实例变量 | 调用静态方法 | 访问静态变量 |
---|---|---|---|---|
实例方法 | √ | √ | √ | √ |
静态方法 | × | × | √ | √ |
5、成员变量局部变量的区别
(1)作用域
成员变量:针对整个类有效。
局部变量:只在某个范围内有效。(一般指的就是方法,语句体内)
(2)存储位置
成员变量:随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中。
局部变量:在方法被调用,或者语句被执行的时候存在,存储在栈内存中。
当方法调用完,或者语句结束后,就自动释放。
(3)初始值
成员变量:有默认初始值。
局部变量:没有默认初始值,使用前必须赋值。
6、静态变量成员变量的区别
A:调用方式
静态变量也称为类变量,可以直接通过类名调用。也可以通过对象名调用。
这个变量属于类。
成员变量也称为实例变量,只能通过对象名调用。这个变量属于对象。
B:存储位置
静态变量存储在方法区长中的静态区。
成员变量存储在堆内存。
C:生命周期
静态变量随着类的加载而存在,随着类的消失而消失。生命周期长。
成员变量随着对象的创建而存在,随着对象的消失而消失。
D:与对象的相关性
静态变量是所有对象共享的数据。
成员变量是每个对象所特有的数据。
7、访问修饰符
- default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。
- private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)
- public : 对所有类可见。使用对象:类、接口、变量、方法
- protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。
饰符 | 当前类 | 同一包内 | 子孙类(同一包) | 子孙类(不同包) | 其他包 |
---|---|---|---|---|---|
public | Y | Y | Y | Y | Y |
protected | Y | Y | Y | Y/N(说明) | N |
default | Y | Y | Y | N | N |
private | Y | N | N | N | N |
8、this关键字
this描述的是本类结构调用的关键字,在Java中this关键字可以描述三种结构的调用:
当前类中的属性:this.属性
当前类中的方法:
普通方法: this.方法
构造方法:this() (此时该this调用只能放在构造方法第一行)
描述当前对象
9、String类
String类对象实例化两种方法:
1)String str = "abc" ; //等于是采用匿名对象实例化
2)String str = new String("abc");//调用构造方法进行实例化
这两种实例化方法都可以,但是实际上第一种采用匿名对象,开辟内存存在字符串常量池中,
第二种赋值和new关键字开辟了两块内存,而其中一个内存并未使用,
因此建议使用第一种直接赋值 即匿名对象实例化的方式
10、面向对象的三大特征
1、封装
封装的作用有两个:
第一个作用:保证内部结构的安全。
第二个作用:屏蔽复杂,暴露简单。
一个类体当中的数据,假设封装之后,对于代码的调用人员来说,不需要关心代码的复杂实现,只需要通过一个简单的入口就可以访问了。另外,类体中安全级别较高的数据封装起来,外部人员不能随意访问,来保证数据的安全性。
封装的代码实现两步:
第一步:属性私有化
第二步: 1个属性对外提供两个set和get方法。
外部程序只能通过set方法修改,只能通过get方法读取,可以在set方法中设立关卡来保证数据的安全性。
private声明属性,不允许外部直接访问该属性;
private私有操作原则:
setter(以“private String name”属性为例):public void setName(String n);
getter(以“private String name”属性为例):public String getName();
2、继承
作用:提高代码的复用性,减少重复代码
继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。 关键字:extends
在本职上是特殊——一般的关系,即常说的is-a关系。子类继承父类,表明子类是一种特殊的父类,并且具有父类所不具有的一些属性或方法。从多种实现类中抽象出一个基类,使其具备多种实现类的共同特性 ,当实现类用extends关键字继承了基类(父类)后,实现类就具备了这些相同的属性。
1、子类可以继承父类非私有的属性和方法,不能继承构造方法和私有的属性和方法。
2、可以综合子类的共同特征来去提炼父亲的类。
3、子类在继承父类的各种属性和方法时,也可以有自己的属性和方法。
4、一个子类只能有一个父类,java只能单继承,不能多继承,因为多个类中的方法名相同,方法体不同,不知使用哪个。
5、一个类继承最顶端叫做基类或者超类,所有的超类叫做object 。
6、在继承关系中,如果父类没有无参数的构造方法,如何解决?
1>子类中添加一个和父类构造方法参数列表相同的构造方法,通过super参数传递给父类的构造方法
2>如果父类允许修改的时候,可以在父类中创建一个无参的构造方法
7、在继承关系中,代码块的执行顺序:父静>子静>父构造代码块>父构造方法>子构造代码块>子构造方法
Super()对应this(),调用父类构造方法,实际上这个构造方法在子类中是隐含的,在调用子类构造方法实例化的时候会先调用父类构造方法
子类继承父类后,获取到父类的属性和方法,这些属性和方法在使用前必须先初始化,所以须先调用父类的构造器进行初始化
子类调用父类构造方法实例化不会实例化一个父类对象!!
3、多态
将父类对象应用于子类对象的特征就是面向对象编程中的多态性的体现
多态指的就是在应用程序中出现的“ 重名 ” 现象。多态性允许以统一的风格编写程序,以处理种类繁多的已存在的类及其相关类。这样既降低了维护难度,又节省了时间
Java实现多态有三个必要条件:继承、重写、向上转型。
继承:在多态中必须存在有继承关系的子类和父类。
重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。
只有满足了上述三个条件,我们才能够在同一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而达到执行不同的行为。
Java中多态性可以分为两个不同的展现形式:
1) 方法的多态性
方法的重载:同一个方法名称可以根据传入的参数的类型或个数的不同实现不同功能的执行;
方法的覆写:同一个方法可能根据实现子类的不同有不同的实现;
2)对象的多态性
对象向上转型:父类 父类实例 = 子类实例、自动完成转换;
对象向下转型:子类 子类实例 = (子类) 父类实例、强制完成转换。(具有风险)
一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用类型转为子类引用各类型
还可以通过抽象类和接口来实现
11、方法重载/重写(覆盖)
1、方法重载overload
1.什么情况下我们考虑使用方法重载机制?
当功能相似的时候,建议将方法名定义为一致的,这样代码美观,又方便编程。
注意:如果功能不相似,坚决要让方法名不一致。
2.代码满足什么条件的时候构成了方法重载?
条件1:在同一个类当中
条件2:方法名相同
条件3:形式参数列表不同(类型、个数、顺序)
注意:
方法重载和返回值类型无关,和修饰符列表无关,但是为了规范表示,尽量使得返回值类型相同,并且使得重载的方法按形式参数从少到多或者从多到小的方式进行编写。
3.方法重载的优点?
代码美观
方便代码的编写
在在进行数据的输出的时候,我们可以发现,System.out.println()可以接受各种类型的数据类型,
因此 jdk中System类中的println()方法也实现了方法重载。
2、方法重写(覆盖)override
1.什么情况下我们考虑使用方法重写机制?
在继承关系中,父类作为最基础的类存在其定义的所有结构都是为了完成本类的需求而设计的,但是在很多时候子类由于某些特殊的需要,有可能会定义与父类名称相同的方法或属性,此类情况在面向对象设计中被称为重写。
2.代码满足什么条件的时候构成了方法重写?
此时在子类中可以定义与父类中方法名称、返回值类型、参数类型及个数完全相同的方法的时候,称为方法的重写。
3.访问权限问题
子类利用方法重写可以扩充父类方法的功能,但是在进行方法重写时有一个核心的问题:被子类所重写的方法不能拥有比父类更严格的访问控制权限,对于访问控制权限现在已经接触过三种:“private < default(不写) < public”。
方法重载和方法重写的区别
No. | 区别 | 重载 | 重写 |
---|---|---|---|
1 | 英文单词 | Overloading | Overriding |
2 | 定义 | 方法名称相同、参数的类型及个数不同 | 方法名称、参数类型及个数、返回值类型完全相同 |
3 | 权限 | 没有权限要求 | 被子类所重写的方法不能拥有比父类更严格的访问控制权限 |
4 | 范围 | 发生在一个类之中 | 发生在继承关系类之中 |
12、抽象类abstract
多个类有相同的方法声明,但是方法体不一样。这个时候,我们考虑把方法声明进行抽取。
让子类继承后,自己去实现方法体。没有方法体的方法,我们需要用抽象标志下。
作用:节省代码,提高代码的复用性
1、抽象类格式:访问权限修饰符 abstract class 类名{}
2、抽象方法格式:访问权限修饰符 abstract 返回值类型 方法名(形式参数列表);
注意:
1、如果一个类里有抽象方法,那么这个类必须声明成抽象类。
2、一个类里面可以没有抽象方法,可以有非抽象方法,
3、类继承抽象类:
把子类也用abstract修饰,变成抽象类。
子类重写父类的抽象的方法
4、抽象类不能创建对象。
5、抽象类可以有构造方法,在创建子类的时候,super隐式调用父类的构造方法,将父类的属性和方法放到子类的对象空间里。
6、在继承你关系中,子类能够继承抽象类的各种属性和方法,除了私有的和构造方法。
7、只有公开的才可以和abstract连用,static final private 都不可以。
static属于类方法,不允许覆盖,abstract必须被覆盖。final不能被重写。
13、接口interface
当一个类中的方法都是抽象的时候,java提供了另一种表示方式,叫接口。
作用:规范了代码,提高代码的拓展性
1、格式:访问权限修饰符 interface 接口名称{}
2、实现类的格式:访问权限修饰符 class 实现类名 implements 接口名{必须重写接口中的所有的抽象方法}
3、接口中只有全局常量和抽象方法。
4、书写的时候可以省略部分修饰符,系统会默认给添上。
5、接口在实现的同时去继承,extends在implement前面。
6、接口可以多实现,实现的也必须是接口,方法名可以重复,实现类实现一个就行了,因为没有方法体,不会发生冲突。
抽象和接口的区别
1、关键字:抽象类 abstract 接口interface
2、抽象类继承 extends 接口实现 implements
3、子类继承抽象类和 实现类实现接口的格式不同
4、接口中只有全局变量和抽象方法 抽象类中有各种属性和方法
5、抽象类只能单继承 接口可以多实现
6、抽象类的子类只能继承一个父类 实现类可以实现多个接口,并且还可以继承父类
7、抽象类的作用:提高代码的复用性 接口的作用:1、规范代码2、提高代码的拓展性
接口和抽象类的区别?
接口(interface)和抽象类(abstract class)是支持抽象类定义的两种机制。
接口是公开的,不能有私有的方法或变量,接口中的所有方法都没有方法体,通过关键字interface实现。
抽象类是可以有私有方法或私有变量的,通过把类或者类中的方法声明为abstract来表示一个类是抽象类,被声明为抽象的方法不能包含方法体。子类实现方法必须含有相同的或者更低的访问级别(public->protected->private)。抽象类的子类为父类中所有抽象方法的具体实现,否则也是抽象类。
接口可以被看作是抽象类的变体,接口中所有的方法都是抽象的,可以通过接口来间接的实现多重继承。接口中的成员变量都是static final类型,由于抽象类可以包含部分方法的实现,所以,在一些场合下抽象类比接口更有优势。
相同点:
(1)都不能被实例化
(2)接口的实现类或抽象类的子类都只有实现了接口或抽象类中的方法后才能实例化。
不同点:
(1)接口只有定义,不能有方法的实现,java 1.8中可以定义default方法体,而抽象类可以有定义与实现,方法可在抽象类中实现。
(2)实现接口的关键字为implements,继承抽象类的关键字为extends。一个类可以实现多个接口,但一个类只能继承一个抽象类。所以,使用接口可以间接地实现多重继承。
(3)接口强调特定功能的实现,而抽象类强调所属关系。
(4)接口成员变量默认为public static final,必须赋初值,不能被修改;其所有的成员方法都是public、abstract的。抽象类中成员变量默认default,可在子类中被重新定义,也可被重新赋值;抽象方法被abstract修饰,不能被private、static、synchronized和native等修饰,必须以分号结尾,不带花括号。
(5)接口被用于常用的功能,便于日后维护和添加删除,而抽象类更倾向于充当公共类的角色,不适用于日后重新对立面的代码修改。功能需要累积时用抽象类,不需要累积时用接口。
四、异常
1.异常概念
(1)程序运行过程中的不正常现象就叫异常。
(2)导致程序运行不正常的现象有很多,所以,就有很多的异常对象。
而这些异常对象存在着共性的内容,所以,可以不断的进行抽取。最终形成了异常的体系结构、
2、异常的分类
异常有两种:
编译时被检测异常:
该异常在编译时,如果没有处理(没有抛也没有try),编译失败。
该异常被标识,代表这可以被处理。
运行时异常(编译时不检测)
在编译时,不需要处理,编译器不检查。
该异常的发生,建议不处理,让程序停止。需要对代码进行修正。
3、异常特点
(4)异常体系的特点:
异常体系中的所有类及其子类对象都具备可抛性。也就是说可以被throw和throws关键字所操作。
(5)异常的处理·
A:try…catch…finally
基本格式:
try
{
可能出现异常的代码
}
catch(异常对象)
{
异常处理代码
}
finally
{
释放资源
}
(6)throws和throw的区别
A:有throws的时候可以没有throw。
有throw的时候,如果throw抛的异常是Exception体系,那么必须有throws在方法上声明。
B:throws用于方法的声明上,其后跟的是异常类名,后面可以跟多个异常类,之间用逗号隔开
throw用于方法体中,其后跟的是一个异常对象名
五、IO流
1、IO流概述
(1)用来处理设备(硬盘,控制台,内存)间的数据。
(2)java中对数据的操作都是通过流的方式。
(3)java用于操作流的类都在io包中。
(4)按照流操作的数据的类型不同:分为字节流和字符流。字符流是为了方便中文的操作而来的。
(5)按照流的流向不同分为:输入流,输出流
2、流的分类
按流分向:
输入流:从数据源到程序中的流
输出流:从程序到数据源的流
按数据传输的单位:
字节流:以字节为单位传输数据的流
字符流:以字符为单位传输数据的流
按功能分:
节点流:直接与数据源打交道的流
处理流:不直接与数据源打交道,与其他流打交道
import java.io.*;
import java.util.*;
public class SaveAndReadArrayByWriter{
public static void save(int[][] datas)throws IOException{
PrintWriter pw=new PrintWriter("array.txt");
pw.println(datas.length);
pw.println(datas[0].length);
String content="";
for(int i=0;i<datas.length;i++){
for(int j=0;j<datas[0].length;j++){
if(j<datas[0].length-1){
content+=datas[i][j]+",";
}else{
content+=datas[i][j]+"\n";
}
}
}
pw.print(content);
pw.close();
}
public static void read()throws IOException{
BufferedReader reader=new BufferedReader(new FileReader("array.txt"));
String strRow=reader.readLine();
int row=Integer.parseInt(strRow);
String strCol=reader.readLine();
int col=Integer.parseInt(strCol);
int[][] datas=new int[row][col];
String content="";
for(int i=0;i<datas.length;i++){
content=reader.readLine();
if(content==null) break;
String[] strDatas=content.split(",");
for(int j=0;j<datas[0].length;j++){
datas[i][j]=Integer.parseInt(strDatas[j]);
}
}
System.out.println(Arrays.deepToString(datas));
reader.close();
}
public static void main(String[] args)throws IOException{
int[][] a={{1,2,3},{4,5,6},{7,8,9}};
save(a);
read();
}
}
简答题
1、 请解释常量与变量的区别?
答: 常量就是一个固定的数值。是不可改变的,例如:数字1、2就是一个整型的常量。
变量是利用声明的方式,将内存中的某个内存块保留下来以供程序使用。可以声明的数据类型为整型、字符型、浮点型或是其他数据类型,作为变量的保存之用。变量在程序语言中扮演了最基本的角色。变量可以用来存放数据,而使用变量之前必须先声明它的数据类型。
2、 请解释“&”和“&&”的区别?
&在进行逻辑运算时表示所有判断条件都需要判断,而“&&”为短路与,在前面的判断返回false时后面判断将不再执行,最终的结果就是false。
&还可以应用在位操作上。
3、 请解释“|”和“||”的区别?
|在进行逻辑运算时表示所有判断条件都需要判断,而“|”为短路或,在前面的判断返回true时后面判断将不再执行,最终的结果就是true。
|还可以应用在位操作上。
tas=content.split(",");
for(int j=0;j<datas[0].length;j++){
datas[i][j]=Integer.parseInt(strDatas[j]);
}
}
System.out.println(Arrays.deepToString(datas));
reader.close();
}
public static void main(String[] args)throws IOException{
int[][] a={{1,2,3},{4,5,6},{7,8,9}};
save(a);
read();
}
}
## 简答题
1、 请解释常量与变量的区别?
答: 常量就是一个固定的数值。是不可改变的,例如:数字1、2就是一个整型的常量。
变量是利用声明的方式,将内存中的某个内存块保留下来以供程序使用。可以声明的数据类型为整型、字符型、浮点型或是其他数据类型,作为变量的保存之用。变量在程序语言中扮演了最基本的角色。变量可以用来存放数据,而使用变量之前必须先声明它的数据类型。
2、 请解释“&”和“&&”的区别?
&在进行逻辑运算时表示所有判断条件都需要判断,而“&&”为短路与,在前面的判断返回false时后面判断将不再执行,最终的结果就是false。
&还可以应用在位操作上。
3、 请解释“|”和“||”的区别?
|在进行逻辑运算时表示所有判断条件都需要判断,而“|”为短路或,在前面的判断返回true时后面判断将不再执行,最终的结果就是true。
|还可以应用在位操作上。