java基础
1.字面值常量的分类
<1>.字符串常量,要用""括起来,如"abcds"
<2>.字符常量,要用''括起来,如'a',‘0’
<3>.整数常量,11,12
<4>.小数常量,0.11
<5>.布尔常量,true,false
<6>.空常量,null
2.变量—变量的作用域
变量的定义格式:
数据类型 变量名 = 初始值
8种 数据类型:byte, shot, int, long, float, double, boolean, char
byte b = 10;
short s = 20;
int i = 30; // 32位
long l = 100000L; // 64位
float f = 10.3F; // 32位
double d = 10.2; // 64位
char c = 'a';
boolean b1 = true;
boolean b2 = false;
3.数据类型转换
<1>整形数据默认为int, 浮点型数据默认为double
<2>强制类型转换: 目标类型 变量名 = (目标类型)要转换的值
注意:强制数据类型转换在使用时可能会出现丢失精度的问题。
如:
int a = 10;
byte b = 20;
byte dd = (byte)(a+b);
4.标识符
标识符的组成:数字,字母,下划线(_),美元符号($)
命名规则:
类和接口:大驼峰
方法和变量:小驼峰
常量: 全部大写,用_隔开
包Package:全部小写(其实就是文件夹,用来区分重名类的)
5.运算符
<1>算数运算符:/, %, ++, --
<2>赋值运算符: =, +=, -=
<3>关系运算符: ==, >=, !=, <=, >, <
<4>逻辑运算符:&&, ||, !
<5>三元运算符:?: 如:b=a>2?10:20
6.字符和字符串参与加法运算
<1>字符参与加法运算,其实就是拿该字符在计算机中存储所表示的数据值来运算的(ASIIC 码);
<2>字符串参与加法运算,其实是字符串的拼接;
7.自增、自减运算符
如:++
<1>单独使用,放在变量前或后结果一样,都是自身+1
a++,++a
<2>参与运算:
在变量前,先自增,再以新值进行其他运算
在变量后,先以原值进行其他运算,再自增
8.流程控制结果
<1>Scanner类--键盘录入功能
// 1.导包
import java.util.Scanner;
public class ScannerDemo{
public static void main(String[] args){
// 2.创建键盘录入对象
Scanner sc = new Scanner(System.in);
// 3.接收数据
System.out.println("请输入一个整数:");
int i = sc.nextInt();
System.out.println("i:" + i);
<2>选择流程结果
(1)if语句:一般用做区间值的判断
*如果if语句控制的语句体只有一行代码,那么{}可以省略不写。
if(关系表达式){
//语句体1
}
if(关系表达式){
//语句体1
}else{
//语句体2
}
if(关系表达式1){
//语句体1
}else if(关系表达式1){
//语句体2
}//...
else{
//语句体n
}
(2)switch语句:转换、切换,固定值的判断
表达式的取值类型:byte,short,int,char
jdk5以后可以是:枚举
jdk7以后可以是:String
case值是要跟表达式进行比较的值
default 与if语句中的else类似
switch(表达式){
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
...
default:
语句体n+1;
break;
}
9.循环结构
<1>for循环
for(初始化语句;判断条件语句;控制条件语句){
}
<2>while循环
while(判断条件语句){
}
<3>do-while循环
初始化语句
do{
}while(判断条件语句);
<4>死循环
for(;;){
}
while(true){
}
<5>break与continue
<6>标号循环
label_class:for(){
for(){
if(){
break label_class;
}
}
}
10.Random类
import java.util.Random;
Random r = new Random();
int num = r.nextInt(10);
11.方法
if 没有返回值:返回值类型为void,else:返回值类型
修饰符 返回值类型 方法名(参数类型 参数名1, 参数类型 参数名2){
//方法体语句;
return 返回值;
}
如:
public static void main(String[] args){
//方法体语句;
}
修饰符(public static) 返回值类型(void) 方法名(main)(参数类型() 参数名1,参数类型 参数名2){
return 返回值;
}
定义方法的注意事项:
(1)方法必须定义在类中;
(2)方法之间是平级关系,不能嵌套;
(3)方法返回值类型为void时,可以省略return;
(4)方法没有返回值,也要有返回值类型:void;
(5)return 语句后的数据类型必须和返回值类型匹配;
(6)return 之后不能放置其他语句
方法重载:
在同一个类中的多个方法,它们的方法名相同,参数列表不同的情况。方法重载与返回值类型、修饰符无关。
方法签名:方法名+参数列表
12.数组
(1)数组的定义类型-->数组类型是引用类型
数组中未手动赋值的元素,有默认值0;
格式1:数据类型[] 数组名 = new 数据类型[长度]
如:int[] arr = new int[10]; //数组长度在定义时指定,不可更改
格式2:数据类型[] 数组名 = new 数据类型[]{元素1, 元素2,...}
如:int[] arr2 = new int[]{1,2,3};
格式3:数据类型[] 数组名 = {元素1, 元素2,...} //格式3是格式2的简化形式
如:int[] arr3 = {1,2,3};
(2)数组的访问方式
取值:数组名[索引]
赋值:数组名[索引] = 值;
(3)数组的遍历和初始化
数组长度 int l = arr.length
动态初始化:
整数型:0
浮点数:0.0
字符型:'\u0000'(空字符串)
布尔型:false
引用类型:null
静态初始化:给出初始化值,由系统决定数组长度
(4)方法的调用
<1>引用类型的变量作为参数传递时,传递的是地址值。
<2>基本类型的变量作为参数传递时,传的是值,相当于复制一份,对原始数据没有影响。
13.java开发-面向对象
类的定义:
成员变量:定义在类中,方法外 如:String brand; String model;
成员方法:去掉static修饰符 如:call();sendMessage()
变量使用规则:就近原则,如果方法体语句有该变量,就使用这个变量;如果方法体中没有,就在类的成员变量中寻找。
成员变量与局部变量的区别:
成员变量:有默认初始值;堆内存
局部变量:无默认初始值,必须先赋值再使用;栈内存
*对象作为参数
public class TestStudent{
public static void main(String[] args){
Student stu = new Student();
stu.name = "张三丰";
stu.age = 121;
stu.study();
showAge(stu)
}
public static void showAge(Student s){
System.out.println("学生"+s.name+"的年龄是:"+s.age);
}
}
public class Student{
String name;
int age;
public void study(){
System.out.println(name+"正在努力学习!");
}
}
(1)封装-隐藏对象的属性和实现细节,仅对外提供公共的访问方式
封装的关键:绝不能让类中的方法之间访问其他类的数据(属性),程序仅通过对象的方法与对象的数据进行交互。
(2)继承–子承父业
高内聚,低耦合
class 父类{}
class 子类 extends 父类{}
*子类拥有了父类的非私有成员(成员变量、成员方法)
*继承关系中字父类构造方法的使用
-:在创建子类对象时,优先调用父类构造方法【子类构造方法的第一行,隐含语句super(),用于调用父类默认无参构造】
-:如果父类没有无参构造,可以手动添加 super.父类有参构造,调用父类的有参构造 。
*:方法重写Override:ctrl+enter(快捷键)
-:父类私有方法无法重写;
-:子类方法访问权限不能小于父类方法;
-:子类不能比父类方法抛出更大的异常;
@Override
*:四大权限修饰符,修饰范围从小到大:
private,默认(什么都不写),protected,public
private:强调的是给自己使用
默认:强调的是给同包下的类来使用
protected:强调的是给子类使用
public:强调的是给大家使用
*:方法重载(Overload)和方法重写(Override)
Overload:
-方法名:相同
-参数列表:不同(个数或对应位置类型)
-返回值类型:无关
-修饰符:无关
-定义位置:同一个类
Override:
-方法名:相同
-参数列表:相同
-返回值类型:相同
-修饰符:访问权限不小于被重写方法
-定义位置:子父类中
*:java中的继承特点
-单继承:java只支持类的单继承,但是支持多重继承
java支持接口的多继承,语法为:接口A extends 接口B,接口C,接口D
-父类的私有成员不能继承(成员变量、成员方法)
-构造方法不能继承(构造方法用来初始化类,继承没有意义)
-继承体现了“is a”的关系
(3)多态-事物的不同状态
<1>实现多态的三个步骤:
-:要有继承(或实现)的关系
-:要有方法重写
-:父类引用指向子类对象(is a关系)如:Animal an = new Dog()
*:多态中调用成员方法是“编译看左(左边的类型中有没有这个成员),运行看右(运行时具体用的是右边类中的该成员)”
<2>多态的使用场景:父类可以作为形参的数据类型,这样可以接收其任意的子类对象;
public class TestAnimal{
public static void main(String[] args){
Dog d = new Dog();
d.setName = "哈士奇";
showAnimal(d);
Mouse d = new Mouse();
m.setName = "jerry";
showAnimal(m);
}
public static void showAnimal(Animal a){
a.eat()
}
}
<3>多态关系中成员变量的使用
*成员变量不能重写,遵循“编译看左,运行看左”
编译看左:意思是在编译期间会看左边的类型有没有这个成员,没有就会报错,有就不报错;
运行看左:意思是在运行期间使用的是 左边的类型中的这个成员;
public class Test{
public static void main(String[] args){
Animal animal = new Dog();
System.out.println(animal.name);
Dog dog = new Dog();
System.out.println(dog.name);
}
}
public class Animal{
String name = "Animal";
}
public class Dog extends Animal{
String name = "Dog";
}
<4>多态的好处和弊端(需要类型转换)
-向上转型(自动类型转换):子类型==>父类型 Animal animal = new Dog();
-向下转型(强制类型转换):父类型==>子类型 Dog dog = (Dog)animal;
注意事项:
-:只能在继承层次内进行转换,否则会报ClassCastException
-:将父类对象转换成子类之前,使用instanceof进行检查
if(an instanceof Dog){
Dog dog = (Dog)an;
dog.watch();
}
(4)private与this
private:私有修饰符,一般用来修饰成员变量
public:公有修饰符,一般修饰成员方法
this:表示本类对象的引用,本质是一个对象。相当于python中的self。
(5)构造方法–用来初始化对象,相当于__init__
格式:修饰符 构造方法名(参数列表){}
要求:
构造方法名必须与类名相同;没有返回值;没有返回值类型,连void都没有;
注意事项:
若未提及任何构造方法,系统会给出默认无参构造;
若已提供任何构造方法,系统不再提供无参构造;
构造方法可以重载;
如:
public Student(){
}
(6)JavaBean标准类
必须是具体的、公共的、并且具有无参数的构造方法,提供用来操作成员变量的set和get方法(快捷键alt+insert)。构造方法可以重载。
public class Student{
private String name;
private int age;
public Student(){
}
public Student(String name, int age){
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public void getName(){
return name
}
public void setAge(String age){
this.age = age
}
public void getAge(){
return age
}
}
(7)抽象类-> 包含抽象方法的类,用abstract修饰
public abstract class Animal{}
<1>抽象方法->只有方法声明,没有方法体的方法
public abstract void eat();
<2>抽象类的特点
-修饰符:使用abstract;
-抽象类不能被实例化,只能创建子类对象;
-抽象类子类的两个选择:
*:子类如果是普通类,必须重写父类所有抽象方法;
*:定义成抽象类:子类如果是抽象类,则不用重写抽象方法;
<3>抽象类成员的特点:
-成员变量:
*可以有普通的成员变量;
*也可以有成员常量(final) final int AGE=30;
-成员方法:
*可以有普通方法,也可以有抽象方法;
*抽象类不一定有抽象方法,但有抽象方法的类一定是抽象类(接口);
-构造方法:
像普通类一样有构造方法,且可以重载。
(8)final与static
<1>final的作用
-修饰类:该类不能被继承(如:String,System),但是可以继承其他类;
-修饰的方法:该方法不能被重写,且不能与abstract共存;
-修饰变量:常量,常量值只能赋值一次;final修饰的变量,引用类型的变量,是地址值不能改变,但是属性值可以变化;
<2>static
-修饰成员变量-->类变量:被本类所有对象共享
-修饰成员方法-->类方法(静态方法):静态方法中没有this,所以不能访问非静态成员;
使用场景:只需要访问静态成员;不需要访问对象状态,所需参数都有参数列表显示提供;
公共的静态常量:public final static String NAME="";
(9)接口interface
interface 接口名{}
如:public interface smoking{}
-类与接口的实现(子类)关系,用implements表示
class 类名 implements 接口名
-成员方法:
接口中的成员方法默认含有public abstract
-接口创建对象的特点:
>>*接口不能实例化,可通过多态的方式实例化子类对象;
*接口的子类(实现类),可以是抽象类(不用重写接口中的抽象方法),也可以是普通类(必须重写接口中的所有抽象方法);
-接口中继承关系的特点:
*接口与接口的关系:继承关系,可以是多继承,也可以是单继承;
格式:接口 extends 接口1, 接口2...
*继承与实现的区别:
继承是“is a”的关系,父类中定义共性内容;
实现体现的是“like a”的关系,接口中定义扩展功能;
-接口成员的特点:
<1>接口成员变量:
接口没有成员变量,只有公有、静态的常量:
public static final 常量名=常量值;
<2>接口成员方法:
JDK7以前,公有的、抽象的方法:public abstract 返回值类型 方法名();
JDK8以后,可以有默认方法(default)和静态方法:
public default 返回值类型 方法名(){}
static 返回值类型 方法名(){}
JDK9以后,可以有私有方法:private 返回值类型 方法名(){}
如:
public interface USB{
public static final int NUM = 10;
public abstract void open();
public static void method1(){
System.out.println("我是JDK8的新特性。");
}
public default void method2(){
System.out.println("我是JDK8的新特性。");
}
private void method3(){
System.out.println("我是JDK9的新特性。")
}
}
<3>接口中没有构造方法。
14.JAVA常用工具
(1)Object类
概述:类层次结构最顶层的基类
构造方法: public Object()
成员方法:
int hashCode(); 返回对象的哈希码值
class> getClass(); 返回调用者的字节码文件对象(一个类只有一个字节码文件对象)
String toString(); 返回该对象的字符串表示形式(默认打印的不同对象的地址值,地址值的组成:全类名+@+对象哈希码的无符号的16进制形式)
boolean equals(); 比较两个对象是否相同(默认比较的地址值,无意义,子类一般都会重写)
*注意:
java.lang包下的类可以直接使用,不需要导包
*JavaBean重写Object类的方法
-重写equals(),使用快捷键重写equals方法
(2)Scanner类
简介:扫描器,能够解析字符串(String)和基本数据类型的数据。
构造方法:public Scanner(InputStream is):构造一个扫描器对象,从指定输入流中获取数据参数System.in,对应键盘录入。
成员方法:
hasNextXxx(): 判断是否还有下一个输入项,其中Xxx可能是任意基本数据类型,返回结果为布尔类型
nextXxx(): 获取下一个输入项,其中Xxx肯能是任意基本数据类型,返回对应类型的数据
String nextLine():获取下一行数据,以换行符作为分隔符(结束标记)
String next(): 获取下一个输入项,以空白字符(空格、tab、回车)作为分隔符(结束标记)
*在实际开发中,应用最多的方法就是:
nextInt():接收整数
nextLine():接收字符串
(3)String类
简介:字符串,每个字符串对象都是常量。
构造方法:
String(byte[]): 构造一个String对象,将指定字节数组中的数据转化成字符串。
String(char[]): 构造一个String对象,将指定字符数组中的数据转化成字符串。
*String免new的操作: String s1="abc"
成员方法:
判断功能:
boolean equals(String): 判断当前字符串与给定字符串是否相同,区分大小写。
boolean equalsIgnoreCase(String): 判断当前字符串与给定字符串是否相同,不区分大小写。
boolean startsWith(String): 判断是否以给定字符串开头
boolean isEmpty(): 判断字符串是否为空
获取方法:
int length()
char charAt(int index) 获取指定索引位置的字符
int indexOf(String) 获取指定字符串第一次出现的索引
int lastIndexOf(String) 获取指定字符串最后一次出现的索引
String substring(int) 获取指定索引位置(含)之后的字符串
String substring(int,int)获取从索引start位置(含)起至索引end位置(不含)的字符串
转换功能:
byte[] getBytes() 将字符串转换成字节数组
char[] toCharArray() 将字符串转换成字符数组
static String valueOf() 将指定类型数据转换成字符串
String replace(old,new) 将指定字符(串)替换成新的字符(串)
String[] split(String) 切割字符串,返回切割后的字符串数据,原字符串不变
String trim() 去掉字符串两端的空白字符
(4)StringBuilder和StringBuffer类
简介:可变字符序列,用于构造字符串对象。内部使用自动扩容的数组操作字符串数据。StringBuilder和StringBuffer使用相同的API。
<1>StringBuilder
构造方法:
StringBuilder() 构造一个空的StringBuilder容器
StringBuilder(String str) 构造一个StringBuilder容器,并添加指定字符串
成员方法:
StringBuilder append() 将任意数据添加到StringBuilder容器中,返回自身。
String toString() 将当前StringBuilder容器转成字符串
(5)Date类和Calendar类
<1>Date类
构造方法:
Date(): 构造一个日期对象,当前系统时间,精确到毫秒;
Date(long): 构造一个日期对象,时间为自“1979年1月1日00:00:00 GMT”起,至指定参数的毫秒数;
成员方法:
long getTime(): 将日期对象转换成对应时间的毫秒值;
<2>Calendar类
成员方法:
static Calender getInstance(): 根据当前系统时区和语言环境获取日历对象;
Calender c = Calender.getInstance(); Calender类是抽象类,所以不能new;
int get(int field): 返回给定日历字段的值;
//获取年月日
int year = c.get(Calender.Year);
int month = c.get(Calender.MONTH); //Java中使用0-11的数字表示月份的,对应1-12月;
int day = c.get(Calender.DATE);
void set(int field, int value): 将给定的日历字段设置为指定的值;
(6)基本类型的包装类(java.base/java.lang/)
其中java.lang不需要导包
简介:
基本数据类型不是对象,所以java针对基本数据类型提供了对应的包装类,以对象的形式来使用。
byte ---> Byte
short---> Short
int ---> Integer
long ---> Long
char ---> Character //Character没有parse方法,如果是将字符串转换成char类型,可以通过:String类中的方法toCharArray(),charAt()
float---> Float
double---> Double
boolean---> Boolean
装箱:
基本类型转包装类型(对象类型)
Integer i1 = new Integer(10); //JDK5前使用
Integer i2 = 20;
拆箱:
包装类型(对象类型)转基本类型
int b = i1.intValue();
int c = i2;
成员方法:
static 基本类型parseXxx(String): 将字符串类型的数据转换成对应的基本类型
String s = "10";
int num = Integer.parseInt(s);
15.常用的工具
<1>集合
集合与数组的区别:
集合:元素类型:引用类型(存储基本数据类型时自动装箱);元素个数:不固定,可任意扩容;
数组:元素类型:基本类型,引用类型;元素个数:固定,不能改变容量;
java的集合体系
-单列集合(Collection):
List:ArrayList
Set:HashSet
-双列集合(Map:key,value)
Map:HashMap
<2>List集合:
List al = new ArrayList();
*增强for循环:快捷方式iter+回车
for(数据类型 变量名:数组或者集合对象){
//循环体,变量即元素
}
注意:增强for的底层是迭代器
for(Object obj: list){
//obj是集合中的元素,其本身应该是Integer类型的数据
//还原为Integer类型数据
Integer i1 = (Integer)obj;
System.out.println(obj);
}
*迭代器:
注意:列表迭代器是List体系独有的遍历方式,可以对集合遍历的同时进行添加、删除等操作。
但是必须通过调用列表迭代器的方法来实现。
-迭代器的使用:
Iterator it = list.iterator(); //根据集合对象获取其对象的迭代器对象
while(it.hasNext()){ //如果迭代器中有元素,就一直迭代
String s = (String)it.next();
}
-列表迭代器的使用:
Iterator lit = list.listIterator(); //根据集合对象获取其对象的迭代器对象
while(lit.hasNext()){ //如果迭代器中有元素,就一直迭代
String s = (String)lit.next();
if("b".equals(s)){
lit.add("java");
}
}
<3>泛型
集合类泛型的解释:表示该集合中存放指定类型的元素
List list = new ArrayList<>(); //list只能添加String类型的对象
好处:
类型安全;避免了类型转换;
总结:
泛型一般与集合类相结合使用;
泛型是JDK5的新特性,但是从JDK7开始,后边的泛型可以不用写具体的数据类型了(菱形泛型)。
<4>Collections工具类:
Collections.max();
Collections.sort();
Collections.reverse();
Collections.shuffle();
<5>Set集合
特点:不可重复,无序
Set s = new HashSet<>();
-为什么Set集合没有去重?
Set集合保证元素的唯一依赖:equals()和hashCode()两个方法,需要重写这两个方法,否则调用的是Object类中的方法。
<6>Map集合
键值对(Entry)构成,key--value
Map map = new HashMap<>();
put(); //添加元素(键值对的形式),元素第一次添加,返回null;重复添加,会用新值覆盖旧值,并返回旧值。
keySet(); // 获取所有的key;
get(); //根据key获取value;
16.IO流
<1>异常(Throwable):
-子类:Error (错误,不需要我们处理)
-子类:Exception (异常,这个是我们常说的异常)
-处理方式:
*:try ... catch ...finally
try{
//尝试执行的代码
}catch(Exception e){
//出现问题后的解决方案
}finally{
//写在这里的代码正常情况下一定会执行,一般是用来释放资源的
}
*:throws:
public static void show() throws Exception{
int a = 10/0;
}
public static void main(String[] args) throws Exception{
//方案一:接着抛
//因为show()方法已经抛出一个异常,作为调用者(main函数)必须处理这个异常,main函数接着抛给JVM。
show();
//方案二:try catch
try{
show();
}catch{
}
}
<2>IO流
-:IO流分类:
按数据流向分:
输入流
输出流
按操作方式分:
字节流:
InputStream(顶层抽象类)->(子类):FileInputStream, BufferedInputStream(高效输入流)
OutputStream(顶层抽象类)->(子类):FileOutputStream, BufferedOutputStream
字符流:
Reader(顶层抽象类)-->(子类):FileReader, BufferedReader
Writer(顶层抽象类)-->(子类):FileWriter, BufferedWriter
<3>File类
概述:
构造方法:
File(String pathname) 根据给定字符串路径创建其对应File对象
File(String parent, String child) 根据给定的字符串形式的父目录和子文件(夹)名创建File对象
File(File parent, String child) 根据给定的父目录对象和子文件(夹)名创建File对象
成员方法:
创建功能:
creatNewFile(): 创建文件,如果文件存在,返回false
mkdir(): 创建单级目录
mkdirs(): 创建多级目录,也可以创建单级目录
判断功能:
isDirectory(): 判断File对象是否为目录
isFile(): 判断File对象是否为文件
exists(): 判断File对象是否存在
获取方法:
getAbsolutePath(): 获取绝对路径
getPath(): 获取文件的相对路径
getName(): 获取文件名
list(): 获取指定目录下所有文件(夹)名称数组
listFiles(): 获取指定目录下所有文件(夹)File数组
<4>字符流读写文件–> 注意:字符流只能拷贝纯文本文件。
-.字符流读取文件:
*一次读取一个字节
注意:如果文件读完,返回-1
//1.创建字符输入流对象
Reader reader = new FileReader("lib/1.txt");
//2.读取数据
int chi1 = reader.read();
//3.异常处理
throws IOException
//4.释放资源
reader.close();
*一次读取一个字符数组
Reader reader = new FileReader("lib/1.txt");
char[] chs = new char[3];
int len;
while((len=reader.read(chs)) != -1){
String s = new String(chs,0,len); //chs:表示要操作的数组;0:表示起始索引;len:表示要操作的字符的个数
}
-.字符流写数据:
Writer writer = new FileWriter("dest.txt);
*按单个字符写入
writer.write(int ch);
*按字符数组写入
writer.write(char[] chs, int index, int len);
*按字符串写入
writer.write(String str);
writer.write("写入一个字符串");
writer.close();
-.字符流拷贝文件:
//1.创建字符流读文件对象
//2.创建字符流写文件对象
//3.调用方法都数据
//4.调用方法写数据
//5.异常处理 throws IOException
//6.关闭资源 reader.close(); writer.close();
*按单个字符读写
*按字符数组读写
-.字符缓冲流拷贝文件的标准代码
特点:字符缓冲流自带有缓冲区,大小为8192个字符,即16KB。
//1.创建字符流读文件对象 BufferedReader br = new BufferedReader(Reader reader)
//2.创建字符流写文件对象 BufferedReader br = new BufferedReader(Writer writer)
//3.调用方法都数据
//4.调用方法写数据
//5.异常处理 throws IOException
//6.关闭资源 reader.close(); writer.close();
*:字符缓冲流独有的方法:
BufferedReader成员方法:public String readLine(); 一次读取一行数据并返回读取到的内容,读取不到返回null
BufferedWriter成员方法:public void newLine(); 根据当前操作系统给出对应的换行符
# 换行符:
windows系统:\r\n
mac系统:\r
unix系统:\n
<5>字节流读写文件
与字符流的使用类似!!
-.一次读取一个字节
-.一次读取一个字节数组 byte[] bys = new byte[1024];
//拷贝纯文本文件使用字符流,拷贝其他(图片、音频、视频等)使用字节流。
17.反射
概念:
在程序运行过程中分析类的一种能力。
反射能做什么:
<1>分析类
加载并初始化一个类;
查看类的所有属性和方法;
<2>查看并使用对象
查看一个对象的所有属性和方法;
使用对象的任意属性和方法;
<3>应用场景:
构建通用的工具;
搭建具有高度灵活性和扩展性的系统框架;
(1)获取字节码文件对象的三种方式:
类加载器(ClassLoader):
负责将类的字节码文件(.class文件)加载到内存中,并生成对应的Class对象。
Class对象:java.lang.Class类的对象,也叫字节码文件对象,每个Class对象对应一个字节码文件。
<1>Object类的getClass()方法
Class clazz = 对象名.getClass();
<2>类的静态属性
Class Clazz = 类名.class;
<3>Class类的静态方法(反射)
Class clazz = Class.forName("类的正名"); //正名:包类路径名(包名+类名),如:susu.test.Student
(2)反射方式获取构造方法:
Constructor对象: 构造器对象,属于java.base模块,java.lang.reflect包
通过Class对象获取构造器对象:
getConstructor(Class>...parameterTypes) //返回一个Constructor对象,仅公共构造函数
getDeclaredConstructor(Class>...parameterTypes) //返回一个Constructor对象,可获取私有构造函数
getConstructors() // 返回类所有(不含私有)构造函数的数组
Constructor的常用方法:
String getName() //返回构造函数名
T newInstance(Object...initargs) //使用此构造函数和指定参数创建并初始化对象
*通过反射获取类中的构造方法,并使用
Class clazz = Class.forName("susu.test.Student") //获取类的字节码文件Class
Constructor con2 = clazz.getConstructor(String.class); //获取构造器对象
Student stu = (Student) con2.newInstance("张三"); //创建对应的Student对象
(3)反射方式获取成员方法:
Method:方法类,用来表示所有的成员方法(对象)
调用成员方法:
getMethod(String name,Class>...parameterTypes) //返回一个Method对象,仅公共成员方法
getDeclaredMethod(String,Class>...) //返回一个Method对象,可获取私有成员方法
getMethods() //返回所有(不含私有)方法的数组
Method的常用方法:
public String getName() //获取成员方法名
public Object invoke(Object obj,Object...params) //调用指定方法,obj表示该类的对象,params表示调用该方法所需的参数
public void setAccessible(boolean flag) 是否开启暴力反射(true:开启)
*通过反射获取类中的成员方法:
Class clazz = Class.forName("susu.test.Student") //获取类的字节码文件Class
Constructor con2 = clazz.getConstructor(String.class); //获取构造器对象
Student stu = (Student) con2.newInstance("张三"); //创建对应的Student对象
Method method1 = clazz.getMethod("show1",int.class); //获取成员方法show1()
method1.setAccessible(true); //开启暴力反射(解决不能调用私有方法的问题)
method1.invoke(stu,100);
(4)反射方式获取成员变量:
Field对象:
getField() //返回一个Field对象,仅公共属性
getDeclaredField() //返回一个Field对象,可获取私有属性
getDeclaredFields() //返回此类的所有(含私有)属性的数组
Field类的常用方法:
void set(Object obj,Object value) //设置obj对象的指定属性值为value
void setAccessible(boolean flag) //开启暴力反射:将此属性的可访问性设置为指定的布尔值
最后
public interface USB{
//成员变量
public static final int NUM = 10;
//成员方法
//JDK7及以前的写法
public abstract void open();
//JDK8多了两种写法
public static void method1(){
System.out.println("我是JDK8的新特性。");
}
public default void method2(){
System.out.println("我是JDK8的新特性。");
}
//JDK9多了一种写法
private void method3(){
System.out.println("我是JDK9的新特性。")
}
}