一、JVM 、JDK、JRE
-
JVM: java虚拟机是运行Java字节码(扩展名为.class文件)的虚拟机
-
JDK:java SDK,拥有JRE的一切,还有编译器(javac)和工具(如javadoc和jdb)。它能够创建和编译程序。
-
JRE是java运行时环境,它运行已编译java程序所需的所有内容的集合,包括Java虚拟机(JVM),java类库,java命令和其他的一些基础构件。
Java是编译和解释共存的语言: java先由编译器编译成.class类型的文件,然后通过虚拟机(JVM)从.class文件中读一行解释执行一行。
二、java和C++的区别:
1. 区别:
- 都是都是面向对象的语言,支持封装、继承、多态
- java不提供指针来直接访问内存,程序内存更加安全
- java的类是单继承的,C++支持多重继承,虽然java的类不可以多继承,但是接口可以多继承
- java有自动内存管理垃圾回收机制(GC),不需要程序员手动释放无用内存
- C++同时支持方法重载和操作符重载,但是java只支持方法重载。
-
封装性:指隐藏对象的属性和实现细节,仅对外提供公共访问公式
-
实现java封装:
java中通过将数据声明为私有(private)的,再提供公共(public)的方法:getXXX()和setXXX()实现对该属性的操作,以实现下述目的:
1)隐藏一个类中不需要对外提供的实现细节;
2)使用者只能通过事先制定好的方法来访问数据,可以方便地加入控制逻辑,限制对属性的不合理操作;
3)便于修改,增强代码的可以维护性;
三、字符型常量和字符串常量区别:
1. 字符型常量是单引号引起的字符:‘A’,字符串常量是双引号引起的0个或若干个字符。
- 含义:字符型常量相当于一个整型值(ASCII值),可以参加表达式运算;字符串常量代表一个地址值(该字符串再内存中存放位置)
- 占内存大小:字符常量只占两个字节;字符串常量占若干个字节(注意:char在java中占两个字节)
四、自增自减运算符:++ && –
当运算符放在变量之前时:++a && --a 先自增、减,再赋值。
当运算符放在变量之后时:a++ && a-- 先赋值,再自增、减。
五、continue、break和return的区别:
-
continue:指跳出当前这一循环,继续下一个循环
-
break:指跳出整个循环体,继续执行循环下面的语句
return用于跳出所在方法,结束该方法的运行:
- return:直接使用return方法执行,用于没有返回值函数的方法
- return value:return一个特定值,用于有返回值函数的方法。
六、泛型:和class的使用
-
泛型类的定义:
class Point<T>{ private T x; private T y; public void setX(T x){ //作为参数 this.x = x; } public void setY(T y) { this.y = y; } public T getX() { //作为返回值 return this.x; } public T getY() { return this.y; } } public class Genericity { public static void main(String[] args) { //IntegerPoint使用 Point<Integer> p = new Point<Integer>(); //构造实例 p.setX(new Integer(100)); System.out.println(p.getX()); //100 //floatPoint使用 Point<Float> f = new Point<Float>(); f.setX(new Float(10.12f)); System.out.println(f.getX()); //10.12 //StringPoint使用 Point<String> s = new Point<String>(); s.setX(new String("LONG")); System.out.println(s.getX()); //LONG } }
这个T表示派生自Object类的任何类,比如String、Integer、Double等等,
-
多泛型定义:
//多泛型定义 class MorePoint<T,U>{ private T x; private T y; private U name; public void setX(T x) { this.x = x; } public T getX() { return this.x; } public void setY(T y) { this.y = y; } public T getY() { return this.y; } public void setName(U name) { this.name = name; } public U getName() { return this.name; } }
//多泛型的使用 MorePoint<Integer,String> morePoint = new MorePoint<Integer,String>(); morePoint.setName("多泛型"); System.out.println("morPont.getName:" + morePoint.getName());
-
泛型接口定义及使用:
3.1 使用方法一:非泛型类
要清楚的一点是Generic不是一个泛型类!因为他类名后没有!
interface Info<T>{ //在接口上定义泛型 public T getVar();// 定义抽象方法,抽象方法的返回值就是泛型类型 public void setVar(T x); } class Generic implements Info<String>{ private String var; public Generic(String Var) { this.setVar(Var); } @Override public void setVar(String var) { this.var = var; } @Override public String getVar() { return this.var; } }
public class InfoImpl { public static void main(String[] args) { Generic i = new Generic("接口泛型"); System.out.println(i.getVar()); } }
3.2 使用方法二:泛型类:
在方法一中,我们在类中直接把Info接口给填充好了,但我们的类,是可以构造成泛型类的,那我们利用泛型类来构造填充泛型接口会是怎样呢?
class Generic1<T> implements Info<T>{ //定义泛型接口的子类 private T var; public Generic1(T Var) { this.setVar(Var); } public void setVar(T var) { this.var = var; } public T getVar() { return this.var; } }
在这个类中,我们构造了一个泛型类InfoImpl,然后把泛型变量T传给了Info,这说明接口和泛型类使用的都是同一个泛型变量。
然后在使用时,就是构造一个泛型类的实例的过程,使用过程也不变。Generic1<String> generic1 = new Generic1<String>("定义泛型接口的子类"); System.out.println(generic1.getVar());
使用泛型类来继承泛型接口的作用就是让用户来定义接口所使用的变量类型,而不是像方法一样把它写死。
3.3 构造一个多个泛型变量的类:
interface Info<T>{ public T getVar(); public void setVar(T var); } class InfoImpl<T,K,U> implements Info<U>{ private T x; private K y; private U var; public InfoImpl(U var) { this.setVar(var); } public void setVar(U var) { this.var = var; } public U getVar() { return this.var; } }
public class GenericsDemo1 { public static void main(String[] args) { InfoImpl<Integer,Double,String> i = new InfoImpl<Integer,Double,String>("多个泛型变量"); System.out.println(i.getVar()); } }
3.4 泛型函数定义及使用:
单独在一个函数里面使用泛型:
public class StaticFans { public static void main(String[] args) { StaticFans staticFans = new StaticFans(); staticFans.StaticMathod("静态方法一:");//使用方法一 staticFans.<String>StaticMathod("静态方法二: ");//使用方法二 staticFans.OtherMethod(new Integer(100));//使用方法一 staticFans.<Integer>OtherMethod(new Integer(100)); }//使用方法二 public static <T> void StaticMathod(T a) { System.out.println("staticMathod: " + a.toString()); } public <T> void OtherMethod(T a) { System.out.println("OtherMethod: " + a.toString()); } }
- 方法一:可以像普通方法一样,直接传值,任何值都可以(但必须是派生自Object类的类型,比如String,Integer等),函数会在内部根据传进去的参数来识别当前T的类别。但尽量不要使用这种隐式的传递方式,代码不利于阅读和维护。因为从外观根本看不出来你调用的是一个泛型函数。
- 方法二:与方法一不同的地方在于,在调用方法前加了一个来指定传给的值,如果加了这个来指定参数的值的话,那StaticMethod()函数里所有用到的T类型也就是强制指定了是String类型。这是我们建议使用的方式。
3.5 其他用法:Class类传递及泛型数组:
-
使用Class传递泛型类对象:
-
SuccessModel是自定义的解析类
public class SuccessModel { private boolean success; public boolean isSuccess() { return success; } public void setSuccess(boolean success) { this.success = success; } public static void main(String[] args) { } public static List<SuccessModel> parseArray(String response){ List<SuccessModel> modelList = JSON.parseArray(response,SuccessModel.class); return modelList; } }
public static <T> List<T> parseArray(String response,Class<T> object){ List<T> modeList = JSON.parseArray(response,Object); return modeList; }
-
**定义泛型数组:**String[] list = new String[8];
//定义 public static <T> T[] fun1(T...args){ return arg; } //使用 public static void main(String args[]){ Integer i[] = fun1(1,2,3,4,5,6) ; Integer[] result = fun1(i) ; }
七、== 和equals的区别:
-
==:
对于基本数据类型来说:==比较的是值
对于引用数据类型来收,==比较的是对象的内存地址
equals:不能用于判断基本数据类型的变量,只能用来判断两个对象是否相等。
Object类中定义的equals()和==的作用是相同的:比较两个对象的地址值是否相同,即两个引用是否指向了同一个对象。
像String、Date、File、包装类都重写了Object中的equals方法重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的实体内容是否相同。
-
hashcode()与equals():
-
hash函数:该函数的实现就是一种算法,得出来的值是hash值,hash值在hash表中,不同的hash函数得到的hash值也不同。常用的hash函数有:直接取余法,乘法取整法,平方取中法。
-
hashcode():每个hash值在hash表中对应的位置
-
如何得到hashcode:通过对象的内部地址(也就是物理地址)转换成一个整数,然后该整数通过hash函数的算法得到hashcode。
-
如果两个对象equals相等,那么这两个对象的hashcode一定也相同
-
如果两个对象的hashcode相同,不代表两个对象就相同,只能说明这两个对象在散列存储结构中,存放于同一个位置。
public class hashCode { private String name; private int age; public boolean equals(Object obj) { //传入的对象obj是否是hashCode的实例 if(obj instanceof hashCode) { //强转成hashCode hashCode h = (hashCode)obj; if(this.name == h.name && this.age == h.age){ return true; } } return false; } }
-
-
八、基本数据类型:
java中有8种基本数据类型:
-
6种数字类型:byte、short、int、long、float、double
-
1种字符类型:char
-
1种布尔类型:boolean
-
String是final修饰的,无法被继承,所以String不是java的基本数据类型。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NDSolQFu-1636447613461)(C:\Users\Long\AppData\Roaming\Typora\typora-user-images\1635944592119.png)]
注意:
- java中使用的long类型的数据一定要在数值后面加上L,否则将作为整型解析
- char a = ‘h’ char:单引号,String a = “hello” :双引号
- 这八种基本数据类型对应的包装类有:Integer、Short、Byte、Long、Float、Double、Character、Boolean。包装类型不赋值就是NULL,而基本类型有默认值不是NULL。
- 基本数据类型都直接存放在java虚拟机栈中的局部变量表中
- 包装类型属于对象类型,对象实例都存在于堆中
九、自动装箱与拆箱:
-
装箱:将基本类型用它们对应的引用类型包装起来,调用valueOf()方法。
Integer i= 10 等价于 Integer i= Integer.valueOf(10)
-
拆箱:将包装类型转换为基本数据类型,调用xxxvalue()方法。
int n = i 等价于 int n = i.intValue();
十、8种基本类型的包装类和常量池
-
常量池:在Java中用于保存在编译期已确定的,已编译的class文件中的一份数据,它包括了关于类、方法、接口等中的常量。
-
Byte、Short、Integer、Long这4种包装类默认创建了数值[-128,127]的相应数据类型,Character创建了数值在[0,127]范围的缓存数据,Boolean直接返回true或false。
-
float和double浮点数据类型的包装类并没有实现常量池技术。
Integer i1 = 33; Integer i2 = 33; System.out.println(i1 == i2); //输出true Float i11 = 333f; Float i22 = 333f; System.out.println(i11 == i22); //输出false Double i3 = 1.2; double i4 = 1.2; System.out.println(i3 == i4); //输出false Integer i1 = 40; Integer i2 = new Integer(40); System.out.println(i1 == i2);//输出false
Integer i1 = 40;这一行代码发生装箱,等价于i1 = Integer.valueOf(40)。所以i1直接使用的是常量池中的对象,Integer i2 = new Integer(40);会直接创建新的对象。
十一、方法(函数)
返回值:获取某个方法体中的代码执行后产生的结果。作用是接收出结果,使得它可以用于其他的操作。
方法类型:
-
无参数无返回值的方法:
public void f1(){ System.out.println("无参数无返回值的方法"); }
-
有参数无返回值的方法:
public void f2(int a){ System.out.println(a); }
-
有返回值无参数的方法:
public int f3(){ System.out.println("无参数有返回值的方法"); return 2; }
-
有返回值有参数的方法:
public int f1(int a,int b){
return a+b;
}
-
return在无返回值方法的特殊使用
public void f5(int a){ if(a > 10){ return;//表示结束所在方法的执行 } System.out.println(a); }
十二、静态方法和实例方法:
- 静态方法:类的方法前面加了static关键字,则称之为静态方法,反之为实例方法
- 静态方法和实例方法的区别:
- 外部调用静态方法时,可以使用**“类名.方法名”的方式,也可以使用“对象名.方法名”**的方式。调用静态方法无需创建对象。
- 静态方法只能访问静态成员,实例方法可以访问静态和实例成员。
- 静态方法中也不能使用关键字this。
- 静态方法只能访问静态成员,实例方法可以访问静态和实例成员。
- 外部调用静态方法时,可以使用**“类名.方法名”的方式,也可以使用“对象名.方法名”**的方式。调用静态方法无需创建对象。
public class Person{
public void method(){
//......
}
public static void staticMethod(){
//.....
}
public static void main(String[] args){
Person p = nnew Person();
//调用实例方法
person.method();
//调用静态方法
Person.staticMethod();
}
}
十三、值传递:
**按值调用:**表示方法接收的是调用者提供的值
**按引用调用:**表示方法接收的是调用者提供的变量地址。
Java程序设计语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝,也就是说,方法不能修改传递给它的任何参数变量的内容。
十四、重载和重写:
1. **重载:**发生在同一个类中(或者父类和子类之间),方法名必须相同,参数类型不同,个数不同,顺序不同,方法返回值和修饰符可以不同。
- **重写:**发生在运行期,是子类对父类的允许访问的方法的实现过程进行重新编写。
- 返回值类型、方法名、参数列表必须相同,抛出的异常范围小于等于父类,访问修饰符范围大于等于父类。
- 如果父类的方法访问修饰符为private、final、static,则子类就不能被重写该方法,但是被static修饰的方法能够再次声明。
- 构造方法无法被重写
- **关于重写的返回值类型:**如果方法的返回类型是void和基本数据类型,则返回值重写时不可修改。但是如果方法的返回值是引用类型,重写时是可以返回该引用类型的子类的。
十五、深拷贝和浅拷贝:
1. 深拷贝:对基本数据类型进行值传递,对引用数据类型,创建一个新的对象,并且复制其内容。
- 浅拷贝:对基本数据类型进行值传递,对引用数据类型进行引用传递般的拷贝
十六、成员变量和局部变量:
- final关键字基本使用:
- 修饰类:表明这类不能被继承,注意final类中的所有成员方法都会被隐式地指定为final方法。
- 修饰方法:把方法锁定,防止任何继承类修改它的含义,类的private方法会隐式地被指定为final方法。
- 修饰变量:如果是基本数据类型变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则对其初始化之后便不能指向另一个对象。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Bxl1SI67-1636447613464)(C:\Users\Long\AppData\Roaming\Typora\typora-user-images\1636368135415.png)]
- 对象的相等,比的是内存中存放的内容是否相等。而引用相等,比较的是他们指向的内存地址是否相等。
十七、构造方法:
作用:完成对类的初始化工作
特点:
1. 名字与类名相同
- 没有返回值,但不能用void声明构造函数
- 生成类的对象时自动执行,无需调用
- 构造方法不能被重写,可以被重载
十八、面向对象三大特征:
-
封装:指把一个对象的状态信息(属性)隐藏在对象内部(通过private),不允许外部对象直接访问对象的内部信息。但是可以提供一些被外界访问的方法(get、set方法)来操作属性。
-
继承:子类拥有父类对象所有的属性和方法(包括私有属性和私有方法),但是父类中的私有属性和方法子类是无法访问,只是拥有。子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。子类可以用自己的方式实现父类的方法。
-
多态:表示一个对象具有多种的状态,表现为父类的引用指向子类的实例。
特点:
- 对象类型和引用类型之间具有继承(类)/实现(接口)的关系
- 引用类型变量发出的方法调用到底是哪个类中的方法,必须在程序运行期间才能确定
- 多态不能调用”只在子类存在但在父类不存在的方法“。
- 如果子类重写了父类的方法,真正执行的是子类覆盖的方法,如果子类没有覆盖父类的方法,执行的是父类的方法。
十九、String、StringBuffer和StringBuilder:
-
String是final修饰的,无法被继承,所以String不是java的基本数据类型。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A3CWbQjE-1636447613465)(C:\Users\Long\AppData\Roaming\Typora\typora-user-images\1636372118558.png)]
-
当对字符串进行修改的时候,需要使用StringBuffer和StringBuilder类
-
和String类不同的是,StringBuffer和StringBuilder类的对象能够被多次的修改,并且不产生新的被使用对象
-
StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
-
于 StringBuilder 相较于 StringBuffer 有速度优势,多数情况下建议使用 StringBuilder类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
-
StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以线程安全。StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。
-
操作少量的数据适用:String
-
单线程操作字符串缓冲区操作大量数据:适用StringBuilder
-
多线程操作字符串缓冲区操作大量数据:适用StringBuffer
二十、反射:
-
反射:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任何一个对象,都能够调用它的任意方法和属性,并且能改变它的属性。
-
得到Class的三种方式:
package javaGuide; import java.lang.reflect.Field; import java.lang.reflect.Modifier; /** * @ClassName: Person * @Description: * @author: * @date: 2021年11月8日 下午8:30:31 * @param: */ public class Person { private String name = "long"; public int age = 19; public Person() { } private void say() { System.out.println("private say()..."); } public void work() { System.out.println("public work()..."); } public static void main(String[] args) { //1、通过对象调用 getClass() 方法来获取,通常应用在:比如你传过来一个 Object //2、类型的对象,而我不知道你具体是什么类,用这种方法 Person p1 = new Person(); Class class1 = p1.getClass(); //直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高 //说明任何一个类都有一个隐含的静态成员变量 class Class c2 = Person.class; //通过 Class 对象的 forName() 静态方法来获取,用的最多, //但可能抛出 ClassNotFoundException 异常 try { Class c3 = Class.forName("javaGuide.Person"); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
-
一个类在JVM中只会有一个Class实例,即我们对上面获取的 c1,c2,c3进行 equals 比较,发现都是true。
-
通过 Class 类获取成员变量、成员方法、接口、超类、构造方法等。
-
查阅 API 可以看到 Class 有很多方法:
getName():获得类的完整名字。
getFields():获得类的public类型的属性。
getDeclaredFields():获得类的所有属性。包括private 声明的和继承类
getMethods():获得类的public类型的方法。
getDeclaredMethods():获得类的所有方法。包括private 声明的和继承类
getMethod(String name, Class[] parameterTypes):获得类的特定方法,name参数指定方法的名字,parameterTypes 参数指定方法的参数类型。
getConstructors():获得类的public类型的构造方法。
getConstructor(Class[] parameterTypes):获得类的特定构造方法,parameterTypes 参数指定构造方法的参数类型。
newInstance():通过类的不带参数的构造方法创建这个类的一个对象。
二十一、异常:
1. 异常:java中的异常又称为例外,是一个在程序执行期间发生的事件,它中断正在执行程序的正常指令流。
- 在java’中一个异常的产生,主要有以下三种原因:
- Java内部错误发生异常,Java虚拟机产生的异常
- 编写的程序代码中的错误所产生的异常,例如空指针异常、数组越界异常等
- 通过throw语句手动生成的异常,一般用来告知该方法的调用者一些必要的信息。
- 我们把生成异常对象,并把它提交给运行时系统的过程称为拋出(throw)异常。运行时系统在方法的调用栈中查找,直到找到能够处理该类型异常的对象,这一个过程称为捕获(catch)异常。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rLXdCyiE-1636447613468)(C:\Users\Long\AppData\Roaming\Typora\typora-user-images\1636377099582.png)]
Throwable 类是所有异常和错误的超类,下面有 Error 和 Exception 两个子类分别表示错误和异常。其中异常类 Exception 又分为运行时异常和非运行时异常,这两种异常有很大的区别,也称为不检查异常(Unchecked Exception)和检查异常(Checked Exception)。
- Exception 类用于用户程序可能出现的异常情况,它也是用来创建自定义异常类型类的类。
- Error 定义了在通常环境下不希望被程序捕获的异常。一般指的是 JVM 错误,如堆栈溢出。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MOSgLaF2-1636447613470)(C:\Users\Long\AppData\Roaming\Typora\typora-user-images\1636377250581.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mvqyjZ0w-1636447613471)(C:\Users\Long\AppData\Roaming\Typora\typora-user-images\1636377264654.png)]
-
Throwable常用方法:
- public String getMessage():返回异常发生时的简要描述
- public String toString():返回异常发生时的详细信息
- public String getLocalizedMessage():返回异常对象的本地化信息。使用Throwable的子类覆盖这个方法,可以生成本地化信息。如果子类没有覆盖该方法,则该方法返回的信息与getMessage()返回的结果相同。
- public void printStackTrace():在控制台上打印Throwable对象封装的异常信息。
-
try-catch-finally:
- try块:用于捕获异常。其后可接零个或多个catch块,如果没有catch块,则必须跟一个finally块。
- catch块:用于处理try捕获到的异常。
- finally块:无论是否捕获或处理异常,finally块里的语句都会被执行。当在try块或catch块中遇到return语句时,finally语句块将在方法返回之前被执行。
- 以下3种特殊情况下,finally块不会被执行:
- 在try或finally块中用了System.exit(int)退出程序。但是,如果System.exit(int)在异常语句之后,finally还是会被执行
- 程序所在的线程死亡
- 关闭CPU
二十二、I/O流:
-
序列化:将数据结构或对象转换成二进制字节流的过程
-
反序列化:在序列化的过程中所产生的二进制字节流转换成数据结构或对象的过程
-
序列号的主要目的是通过网络传输对象或者说将对象存储到文件系统、数据库、内存中。
-
对于不想进行序列号的变量,使用transient关键字修饰。
-
transient关键字的作用:阻止实例中那些用此关键字修饰的变量序列化,当对象被反序列化时,被transient修饰的变量值不会被持久化和恢复。
关于transient:
- transient只能修饰变量,不能修饰类和方法
- transient修饰的变量,在反序列化后变量值将会被置成类型的默认值。例如,如果是修饰int类型,那么反序列化后的结果就是0.
- static变量因为不属于任何对象(object),所以无论有没有transient关键字修饰,均不会被序列化。
二十三、获取用键盘输入常用的两种方法:
Scanner:
- nextInt():只读取数值,剩下的"\n"还没有读取,并将光标放在本行中,如果想要在nextInt()后读取一行,就得在nextInt()之后额外加上cin.nextLine()。
- next():只读空格之前的数据,并且光标指向本行
- nextLine():读取包含单词之间空格的输入(即,它读取到行尾 \n)。 读取输入后,nextLine() 将光标定位在下一行。
public class Input {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
//input.close();
System.out.println("输入:");
String s1 = input.nextLine();
System.out.println("s1为:" + s1);
System.out.println("输入s3:" );
int s3 = input.nextInt();
System.out.println("s3为:" + s3);
System.out.println("输入s2:" );
String s2 = input.next();
System.out.println("s2为:" + s2);
}
}
BufferedReader:
BufferedReader类从字符输入流中读取文本缓冲字符,以便有效的读取字符,数组和行。可以通过构造函数指定缓冲区大小也可以使用默认大小。
import java.io.*;
/**
* @ClassName: BufferReaderdemo01
* @Description:
* @author:
* @date: 2021年11月9日 下午4:29:35
* @param:
*/
public class BufferReaderdemo01 {
public static void main(String[] args) {
BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
String str = null;
System.out.println("请输入内容: ");
try {
str = buf.readLine(); //读取一行数据
}catch(IOException e){
e.printStackTrace(); //输出信息
}
System.out.println("输入的内容为: " + str);
}
}
不仅可以接收键盘输入,还可以将文件中的内容读取到缓冲区之中 然后调用readLine()方法将缓冲区中的全部内容转为字符串。实例如下:
import java.io.* ;
public class BufferedReaderDemo01{
public static void main(String args[]){
BufferedReader buf = null ; // 声明对象
buf = new BufferedReader(new InputStreamReader(System.in)) ; // 将字节流变为字符流
String str = null ; // 接收输入内容
System.out.print("请输入内容:") ;
try{
str = buf.readLine() ; // 读取一行数据
}catch(IOException e){
e.printStackTrace() ; // 输出信息
}
System.out.println("输入的内容为:" + str) ;
}
};
IO流划分:
- 按照流的流向划分,可以分为输入流和输出流
- 按照操作单元划分,可以划分为字节流和字符流
- 按照流的角色划分为节点流和处理流
- InputStream/Reader:所有的输入流的基类,前者是字节输入流,后者是字符输入流
- OutputStream/Writer:所有输出流的基类,前者是字节输出流,后者是字符输出流
- 字符流是由Java虚拟机将字节转换得到的