JAVA学习笔记
一.idea快捷键使用
sout: system.out.println();
psvm:public static void main(String[] args);
Ctrl+/ 或 Ctrl+Shift+/ #注释代码;
#Alt + 回车 #导入包,自动修正
Alt + Insert #生成代码(如GET,SET方法,构造函数等)
Ctrl + Alt + T #生成try catch
Ctrl + Alt + I #自动缩进
cmd指令
二.尚硅谷课堂整理
2.1 杂乱无章
自动类型转换,java中 有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算。
byte,short,char之间不会相互转换,他们三者在计算时首先转换为int类型。
强制类型转换,从容量大的数据类型转换到容量低的数据类型
int a=10;
float b=(float)a;
前++后++(–一样)
a=2;b=++a;#先加一,再运算
a=2;b=a++;#先运算,再加一
通常我们使用短路与和短路或 &&,||
异或(a**^**b),交换两个整数的值而不必用第三个参数
位运算符 <<(左移),>>(右移),>>>(无符号右移)
三元运算符:要求表达式1和表达式2结果为同种类型
switch case :switch(表达式)中表达式的值必须是下述几种类型之一:byte,short,char,int,枚举 (jdk 5.0),String (jdk 7.0);
switch (i) {
case 0:
System.out.println("zero");
break;
case 1:
System.out.println("one");
break;
default:#default是可选的
System.out.println("default");
break;
}
break,continue
2.2数组
一维数组
声明:声明时不能指定其长度,例:int a[5];
type var[]或type[] var
初始化分静态初始化和动态初始化
#静态初始化
int arr[] = new int[]{ 3, 9, 8};
或
int[] arr = {3,9,8};
#动态初始化
int[] arr = new int[3];
arr[0] = 3;
arr[1] = 9;
arr[2] = 8;
#获取数组长度
len=arr.length;
多维数组
int[][] arr = new int[3][2];#动态初始化1
int[][] arr = new int[3][];#动态初始化2,每个一维数组默认#初始化为null
int[][]arr = new int[][3]; #非法
int[][] arr = new int[][]{{3,8,2},{2,7},{9,0,1,6}};#静态初始化
二分查找
int[] arr3 = new int[]{-99,-54,-2,0,2,33,43,256,999};
boolean isFlag = true;
int number = 256;
int head = 0;
int end = arr3.length - 1;
while(head <= end){
int middle = (head + end) / 2;
if(arr3[middle] == number){
System.out.println("找到指定的元素,索引为:" + middle);
isFlag = false;
break; }else if(arr3[middle] > number){
end = middle - 1;
}else{
head = middle + 1;
} }
if(isFlag){
System.out.println("未找到指定的元素");
}
快速排序
public class QuickSort {
public static void quickSort(int[] arr,int low,int high){
int i,j,temp,t;
if(low>high){
return;
}
i=low;
j=high;
temp = arr[low];
while (i<j) {
while (temp<=arr[j]&&i<j) {
j--;
}
while (temp>=arr[i]&&i<j) {
i++;
}
if (i<j) {
t = arr[j];
arr[j] = arr[i];
arr[i] = t;
}
}
arr[low] = arr[i];
arr[i] = temp;
quickSort(arr, low, j-1);
quickSort(arr, j+1, high);
}
public static void main(String[] args){
int[] arr = {10,7,2,4,7,62,3,4,2,1,8,9,19};
quickSort(arr, 0, arr.length-1);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
Arrays工具类的使用
boolean equals(int[] a,int[] b);//判断两个数组是否相等。
String toString(int[] a);//输出数组信息
void fill(int[] a,int val);//将指定值填充到数组之中。
void sort(int[] a);//对数组进行排序。
int binarySearch(int[] a,int key);//对排序后的数组进行二分法检索指定的值。
//用法示例
int [] numbers = {5,900,1,5,77,30,64,700};
Arrays.sort(numbers);
2.3.面向对象
面向对象三大特征:封装,继承,多态
类的成员构成:
匿名对象
new Person();
重载和重写的区别:
重载是类名一样,但是参数个数或者类型不一样
重写是类名,参数个数类型一样,但是方法体内部不一样
传递个数可变的形参,可变形参需要放在最后
public static void test(int a ,String[] books);
public static void test(int a ,String…books);
四种访问权限的范围
构造器
this关键字
MVC设计模式
import导包
import 包名. 类名;
import pack1.pack2.Test;
**继承extends **:Java只支持单继承和多层继承,不允许多重继承
super指代父类,注意第一点很重要,经常会出错
多态:父类的引用指向子类的对象
Person p = new Student();
Object o = new Person();
o = new Student();
虚拟方法调用:
子类中定义了与父类同名同参数的方法,在多态情况下,将此时父类的方法称为虚拟方法,父
类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法
确定的。
Person e = new Student();
e.getInfo();
instanceof 操作符
x instanceof A:检验x是否为类A的对象,返回值为boolean型。
e instanceof Student
Object类,这是所有类的父类,一般我们需要在其他继承类中重写equals和toString方法
getClass()
toString()
finalize()
equals()
hashCode()
wait()
notify()
notifyAll()
包装类
基本类型、包装类与String类间的转换**
static关键字
在Java类中,可用static修饰属性、方法、代码块、内部类,先于对象的产生,可直接被类调用
Class.static
在static方法内部只能访问类的static修饰的属性或方法,不能访问类的非static的结构。
static修饰的方法不能被重写
static用法实例:单例模式(即只能存在一个对象实例)
优点:由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决。
? 分为饿汉式和懒汉式(线程不安全)
class Singleton {
private Singleton() {
}
private static Singleton single = new Singleton();
public static Singleton getInstance() {
return single; }
}
class Singleton {
private Singleton() {
}
private static Singleton single;
public static Singleton getInstance() {
if(single == null) {
single = new Singleton();
}
return single; }
}
代码块(初始化块):修饰符只能为static或缺省
静态代码块:用static 修饰的代码块
1. 可以有输出语句。
2. 可以对类的属性、类的声明进行初始化操作。
3. 不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。
4. 若有多个静态的代码块,那么按照从上到下的顺序依次执行。
5. 静态代码块的执行要先于非静态代码块。
6. 静态代码块随着类的加载而加载,且只执行一次。
非静态代码块:没有static修饰的代码块
1. 可以有输出语句。
2. 可以对类的属性、类的声明进行初始化操作。
3. 除了调用非静态的结构外,还可以调用静态的变量或方法。
4. 若有多个非静态的代码块,那么按照从上到下的顺序依次执行。 5. 每次创建对象的时候,都会执行一次。且先于构造器执行。
class Person {
public static int total;
static {
total = 100;
}
……
}
final关键字
static final:全局常量
抽象类
abstract class A {
abstract void m1();
public void m2() {
System.out.println("A类中定义的m2方法");
} }
多态的应用:模板设计模式
换句话说,在软件开发中实现一个算法时,整体步骤很固定、通用,这些步骤已经在父类中写好了。但是某些部分易变,易变部分可以抽象出来,供不同子类实现。这就是一种模板模式。
接口(interface):接口可以实现多继承,implements
public interface Runner {
int ID = 1;
void start();
public void run();
void stop();
}
public interface Runner {
public static final int ID = 1;
public abstract void start();
public abstract void run();
public abstract void stop();
}
先写extends,后写implements
class SubClass extends SuperClass implements InterfaceA{ }
代理模式:代理设计就是为其他对象提供一种代理以控制对这个对象的访问
jdk8.0中接口新增了静态方法和默认方法(default)
public interface AA {
double PI = 3.14;
public default void method() {
System.out.println("北京");
}
default String method1() {
return "上海";
}
public static void method2() {
System.out.println(“hello lambda!");
} }
类优先原则
若一个接口中定义了一个默认方法,而父类中也定义了一个同名同参数的非抽象方法,则不会出现冲突问题。接口中具有相同名称和参数的默认方法会被忽略
interface Filial {
default void help() {
System.out.println("老妈,我来救你了");
} }
interface Spoony {
default void help() {
System.out.println("媳妇,别怕,我来了");
} }
class Man implements Filial, Spoony { @Override
public void help() {
System.out.println("我该怎么办呢?");
Filial.super.help();
Spoony.super.help();
} }
内部类
分成员内部类和局部内部类
成员内部类:生成方式(Class1.new class2())
局部内部类:只能声明在方法或者代码块中,只能在声明它的方法或代码块中使用,而且是先声明后使用。
2.4异常处理
Java程序在执行过程中所发生的异常事件可分为两类:*Error(Java虚拟机无法解决的严重问题。)和Exception(其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。)
Exception分类:编译时异常和运行时异常
编译器要求Java程序必须捕获或声明所有编译时异常。(先编译后运行)
异常处理机制1:try-catch-finally
异常处理机制2:throws +异常类型
try{
......
}
catch( ExceptionName1 e ){
e.getMessage()
e.printStackTrace()
}
catch( ExceptionName2 e ){
......
}[ finally{
......
} ]
public void readFile(String file) throws FileNotFoundException {
……
FileInputStream fis = new FileInputStream(file);
..……
}
public class A {
public void methodA() throws IOException {
……
} }
public class B1 extends A {
public void methodA() throws FileNotFoundException {
……
} }
public class B2 extends A {
public void methodA() throws Exception {
……
} }
手动抛出异常–throw
class MyException extends Exception {
static final long serialVersionUID = 13465653435L;
private int idnumber;
public MyException(String message, int id) {
super(message);
this.idnumber = id; }
public int getId() {
return idnumber; } }
public class MyExpTest {
public void regist(int num) throws MyException {
if (num < 0)
throw new MyException("人数为负值,不合理", 3);
else
System.out.println("登记人数" + num);
}
public void manager() {
try {
regist(100);
} catch (MyException e) {
System.out.print("登记失败,出错种类" + e.getId());
}
System.out.print("本次登记操作结束");
}
2.5多线程–Thread
并行与并发:
**并行:**多个CPU同时执行多个任务。比如:多个人同时做不同的事。
**并发:**一个CPU(采用时间片)同时执行多个任务。比如:秒杀、多个人做同一件事。
创建多线程的2种方式:1.继承Thread类的方式,2.实现Runnable接口的方式
方式一
方式二
1) 定义子类,实现Runnable接口。
2) 子类中重写Runnable接口中的run方法。
3) 通过Thread类含参构造器创建线程对象。
4) 将Runnable接口的子类对象作为实际参数传递给Thread类的构造器中。
5) 调用Thread类的start方法:开启线程,调用Runnable子类接口的run方法。
class MyThread implements Runnable{
public void run()
{
}
}
MyThread mThread=new MyThread();
Thread t1=new Thread(mThread);
t1.start();
Thread类的方法
void start(): 启动线程,并执行对象的run()方法
run(): 线程在被调度时执行的操作
String getName(): 返回线程的名称
void setName(String name):设置该线程名称
static Thread currentThread(): 返回当前线程。在Thread子类中就是this,通常用于主线程和Runnable实现类 static void yield():线程让步,使用 yield () 的目的是让具有相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证 yield () 达到谦让目的,因为放弃 CPU 执行权的线程还有可能被线程调度程序再次选中。
join() :当某个程序执行流中调用其他线程的 join() 方法时,调用线程将被阻塞,直到 join() 方法加入的 join 线程执行完为止
static void sleep(long millis):(指定时间:毫秒)
stop(): 强制线程生命期结束,不推荐使用
boolean isAlive():返回boolean,判断线程是否还活着 getPriority() :返回线程优先值
setPriority(int newPriority) :改变线程的优先级
notify():唤醒正在排队等待同步资源的线程中优先级最高者结束等待
notifyAll ():唤醒正在排队等待资源的所有线程结束等待. wait():令当前线程挂起并放弃CPU、同步资源并等待,使别的线程可访问并修改共享资源,而当前线程排队等候其他线程调用notify()或notifyAll()方法唤醒,唤醒后等待重新获得对监视器的所有权后才能继续执行。
线程的几种状态及其转换图
Synchronized:同步线程-------隐式锁
可以同步代码块和方法
锁:
同步方法的锁:静态方法(类名.class)、非静态方法(this)
同步代码块:自己指定,很多时候也是指定为this或类名.class
一个线程需要共用一把锁,否则无法达到效果
synchronized (对象){
}
public synchronized void show (String name){
….
}
会释放锁的操作
不会释放锁的操作
死锁
不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁
出现死锁后,不会出现异常,不会出现提示,只是所有的线程都处于阻塞状态,无法继续
lock锁–需要手动开锁闭锁,且只能锁代码块----显式锁
jdk5.0新增的线程创建方式
1.实现Callable
2.使用线程池
2.6.常用类
String是final的,变量和字符串拼接,其结果在堆中,而不是字符串常量池中
String常用方法
StringBuffer----必须用构造器生成
StringBuffer():初始容量为16的字符串缓冲区
StringBuffer(int size):构造指定容量的字符串缓冲区
StringBuffer(String str):将内容初始化为指定字符串内容
常用方法
StringBuffer append(xxx):提供了很多的append()方法,用于进行字符串拼接
StringBuffer delete(int start,int end):删除指定位置的内容
StringBuffer replace(int start, int end, String str):把[start,end)位置替换为str
StringBuffer insert(int offset, xxx):在指定位置插入xxx
StringBuffer reverse() :把当前字符序列逆转
public int indexOf(String str)
public String substring(int start,int end)
public int length()
public char charAt(int n )
public void setCharAt(int n ,char ch)
StringBuilder 和 StringBuffer 非常类似,均代表可变的字符序列,而且提供相关功能的方法也一样
时间API跳过,太过繁琐
比较器-----------这块算法题经常会用到,熟练掌握
分2种
**自然排序:**java.lang.Comparable
**定制排序:**java.util.Comparator
class Goods implements Comparable {
private String name;
private double price;
@Override
public int compareTo(Object o) {
if(o instanceof Goods) {
Goods other = (Goods) o;
if (this.price > other.price) {
return 1;
} else if (this.price < other.price) {
return -1;
}
return 0;
}
throw new RuntimeException("输入的数据类型不一致");
}
}
Goods[] all = new Goods[4];
all[0] = new Goods("War and Peace", 100);
all[1] = new Goods("Childhood", 80);
all[2] = new Goods("Scarlet and Black", 140);
all[3] = new Goods("Notre Dame de Paris", 120);
Arrays.sort(all, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Goods g1 = (Goods) o1;
Goods g2 = (Goods) o2;
return g1.getName().compareTo(g2.getName());
}
});
System.out.println(Arrays.toString(all));
System类–该类的构造器是private的
native long currentTimeMillis()
void exit(int status)
void gc()
String getProperty(String key)
Math类–也是private的
abs 绝对值
acos,asin,atan,cos,sin,tan 三角函数
sqrt 平方根
pow(double a,doble b) a的b次幂
log 自然对数
exp e为底指数
max(double a,double b)
min(double a,double b)
random() 返回0.0到1.0的随机数
long round(double a) double型数据a转换为long型(四舍五入)
toDegrees(double angrad) 弧度—>角度
toRadians(double angdeg) 角度—>弧度
BigInteger与BigDecimal大小和精度都比integer和Double高
2.7枚举类与注解
方式一——自定义枚举类
class Season{
private final String SEASONNAME;
private final String SEASONDESC;
private Season(String seasonName,String seasonDesc){
this.SEASONNAME = seasonName;
this.SEASONDESC = seasonDesc; }
public static final Season SPRING = new Season("春天", "春暖花开");
public static final Season SUMMER = new Season("夏天", "夏日炎炎");
public static final Season AUTUMN = new Season("秋天", "秋高气爽");
public static final Season WINTER = new Season("冬天", "白雪皑皑");
}
方式二——使用enum定义枚举类
public enum SeasonEnum {
SPRING("春天","春风又绿江南岸"),
SUMMER("夏天","映日荷花别样红"),
AUTUMN("秋天","秋水共长天一色"),
WINTER("冬天","窗含西岭千秋雪");
private final String seasonName;
private final String seasonDesc;
private SeasonEnum(String seasonName, String seasonDesc) {
this.seasonName = seasonName;
this.seasonDesc = seasonDesc; }
public String getSeasonName() {
return seasonName; }
public String getSeasonDesc() {
return seasonDesc; } }
枚举类的主要方法
values()
valueOf(String str)
toString()
注解
Annotation 其实就是代码里的特殊标记, 这些标记可以在编译, 类加载, 运行时被读取, 并执行相应的处理。通过使用 Annotation, 程序员可以在不改变原有逻辑的情况下, 在源文件中嵌入一些补充信息。代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。Annotation 可以像修饰符一样被使用, 可用于修饰包,类,构造器, 方法, 成员变量, 参数,局部变量的声明, 这些信息被保存在Annotation 的 “name=value” 对中。
使用 Annotation 时要在其前面增加 @ 符号, 并把该 Annotation 当成一个修饰符使用。用于修饰它支持的程序元素
@Override
@Deprecated
@SuppressWarnings
自定义注解
@MyAnnotation(value="尚硅谷")
public class MyAnnotationTest {
public static void main(String[] args) {
Class clazz = MyAnnotationTest.class;
Annotation a = clazz.getAnnotation(MyAnnotation.class);
MyAnnotation m = (MyAnnotation) a;
String info = m.value();
System.out.println(info);
} }
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface MyAnnotation{
String value() default "auguigu"; }
四个元注解
可重复注解
2.8java集合–collection和map
Collection接口:单列数据,定义了存取一组对象的方法的集合
List:元素有序、可重复的集合
Set:元素无序、不可重复的集合
Map接口:双列数据,保存具有映射关系“key-value对”的集合
collection接口方法
add(Object obj)
addAll(Collection coll)
int size()
void clear()
boolean isEmpty()
boolean contains(Object obj)
boolean containsAll(Collection c)
boolean remove(Object obj)
boolean removeAll(Collection coll)
boolean retainAll(Collection c)
boolean equals(Object obj)
Object[] toArray()
hashCode()
iterator()
iterator迭代器
迭代器的方法
Iterator iterator = coll.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
foreach循环遍历集合元素
List集合
void add(int index, Object ele)
boolean addAll(int index, Collection eles)
Object get(int index)
int indexOf(Object obj)
int lastIndexOf(Object obj)
Object remove(int index)
Object set(int index, Object ele)
List subList(int fromIndex, int toIndex)
ArrayList本质上是一个变长的数组,LinkedList是底层是由双向链表写的,vector与ArrayList差不多,但vector的线程是安全的。
在各种list中,最好把ArrayList作为缺省选择。当插入、删除频繁时,使用LinkedList;Vector总是比ArrayList慢,所以尽量避免使用。
vector新增方法
void addElement(Object obj)
void insertElementAt(Object obj,int index)
void setElementAt(Object obj,int index)
void removeElement(Object obj)
void removeAllElements()
set集合
set接口没有提供额外的方法,Set 集合不允许包含相同的元素,Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals() 方法
HashSet–底层也是数组,初始容量为16,当如果使用率超过0.75,(16*0.75=12)
就会扩大容量为原来的2倍。(16扩容为32,依次为64,128…等)
LinkedHsahSet
LinkedHashSet 是 HashSet 的子类,LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,但它同时使用双向链表维护元素的次序,这使得元素看起来是以插入顺序保存的。
TreeSet
TreeSet 是 SortedSet 接口的实现类,TreeSet 可以确保集合元素处于排序状态。底层使用红黑树结构存储数据
Map
HashMap是 Map 接口使用频率最高的实现类
Map常用方法
HashMap底层
数组+链表结构–JDK 7,HashMap是数组+链表+红黑树实现–JDK 8
允许使用null键和null值
当数组元素大于现有元素×负载因子的时候,数组先开始扩容
LinkedHashMap
LinkedHashMap 是 HashMap 的子类,在HashMap存储结构的基础上,使用了一对双向链表来记录添加元素的顺序
TreeMap
TreeMap 可以保证所有的 Key-Value 对处于有序状态,底层使用红黑树结构存储数据
Hashtable
与HashMap不同,Hashtable 不允许使用 null 作为 key 和 value,Hashtable是线程安全的,Hashtable 也不能保证其中 Key-Value 对的顺序
Properties
Properties 类是 Hashtable 的子类由于属性文件里的 key、value 都是字符串类型,所以 Properties 里的 key 和 value 都是字符串类型
存取数据时,建议使用setProperty(String key,String value)方法和getProperty(String key)方法
Properties pros = new Properties();
pros.load(new FileInputStream("jdbc.properties"));
String user = pros.getProperty("user");
System.out.println(user);
Collections工具类——一个操作 Set、List 和 Map 等集合的工具类
reverse(List)
shuffle(List)
sort(List)
sort(List,Comparator)
swap(List,int, int)
Object max(Collection)
Object max(Collection,Comparator)
Object min(Collection)
Object min(Collection,Comparator)
int frequency(Collection,Object)
void copy(List dest,List src)
boolean replaceAll(List list,Object oldVal,Object newVal)
2.9泛型
泛型实例
Set<Entry<String,Integer>> entrySet = map.entrySet();
Iterator<Entry<String,Integer>> iterator = entrySet.iterator();
while(iterator.hasNext()){
Entry<String,Integer> entry = iterator.next();
System.out.println(entry.getKey() + "--->" + entry.getValue());
}
自定义泛型
泛型T只能是类,不能用基本数据类型填充。但可以使用包装类填充
泛型如果不指定,将被擦除,泛型对应的类型均按照Object处理,但不等价于Object
在静态方法中不能使用类的泛型,异常类不能是泛型的,不能在try-catch中使用泛型定义
不能使用new E[]。但是可以:E[] elements = (E[])new Object[capacity];
父类有泛型,子类可以选择保留泛型也可以选择指定泛型类型:
class Father<T1, T2> {
}
class Son1 extends Father {
}
class Son2 extends Father<Integer, String> {
}
class Son3<T1, T2> extends Father<T1, T2> {
}
class Son4<T2> extends Father<Integer, T2> {
}
泛型方法
public class DAO {
public <E> E get(int id, E e) {
E result = null;
return result; } }
如果B是A的一个子类型(子类或者子接口),而G是具有泛型声明的类或接口,G并不是G的子类型!
通配符——?
比如:List<?> ,Map<?,?>,是各种泛型的父类
读取List<?>的对象list中的元素时,永远是安全的,因为不管list的真实类型是什么,它包含的都是Object。
写入list中的元素时,不行。因为我们不知道c的元素类型,我们不能向其中添加对象。但是可以写入null,因为null是任何类型的子类。
public static void main(String[] args) {
List<?> list = null;
list = new ArrayList<String>();
list = new ArrayList<Double>();
list.add(null);
List<String> l1 = new ArrayList<String>();
List<Integer> l2 = new ArrayList<Integer>();
l1.add("尚硅谷");
l2.add(15);
read(l1);
read(l2);
}
public static void read(List<?> list) {
for (Object o : list) {
System.out.println(o);
} }
public static <?> void test(ArrayList<?> list){
}
class GenericTypeClass<?>{
}
ArrayList<?> list2 = new ArrayList<?>();
有限制的通配符
上限extends:使用时指定的类型必须是继承某个类,或者实现某个接口,即<=
下限super:使用时指定的类型不能小于操作的类,即>=
<? extends Number> (无穷小 , Number]
<? super Number> [Number , 无穷大)
<? extends Comparable>
public static void printCollection3(Collection<? extends Person> coll) {
Iterator<?> iterator = coll.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
} }
public static void printCollection4(Collection<? super Person> coll) {
Iterator<?> iterator = coll.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
} }
2.10 IO流
File类
File 能新建、删除、重命名文件和目录,但 File 不能访问文件内容本身。如果需要访问文件内容本身,则需要使用输入/输出流。
public File(String pathname)
public File(String parent,String child)
public File(File parent,String child)
File类功能
public String getAbsolutePath()
public String getPath()
public String getName()
public String getParent()
public long length()
public long lastModified()
public String[] list()
public File[] listFiles()
public boolean renameTo(File dest)
public boolean isDirectory()
public boolean isFile()
public boolean exists()
public boolean canRead()
public boolean canWrite()
public boolean isHidden()
public boolean createNewFile()
public boolean mkdir()
public boolean mkdirs()
public boolean delete()
流–对数据的输入输出操作方式
流分类
按操作数据单位不同分为:字节流(8 bit),字符流(16 bit)
按数据流的流向不同分为:输入流,输出流
按流的角色的不同分为:节点流,处理流
四个基本流
IO流体系
InputStream和Reader的方法
int read()
int read(byte[] b)
int read(byte[] b, int off,int len)
public void close() throws IOException
OutputStream 和 Writer的方法
void write(int b/int c);
void write(byte[] b/char[] cbuf);
void write(byte[] b/char[] buff, int off, int len);
void flush();
void close(); 需要先刷新,再关闭此流
节点流(文件流)
FileReader fr = null;
try {
fr = new FileReader(new File("c:\\test.txt"));
char[] buf = new char[1024];
int len;
while ((len = fr.read(buf)) != -1) {
System.out.print(new String(buf, 0, len));
}
} catch (IOException e) {
System.out.println("read-Exception :" + e.getMessage());
} finally {
if (fr != null) {
try {
fr.close();
} catch (IOException e) {
System.out.println("close-Exception :" + e.getMessage());
} } }
缓冲流–提高数据读写的速度
缓冲流要“套接”在相应的节点流之上
BufferedReader br = null;
BufferedWriter bw = null;
try {
br = new BufferedReader(new FileReader("d:\\IOTest\\source.txt"));
bw = new BufferedWriter(new FileWriter("d:\\IOTest\\dest.txt"));
String str;
while ((str = br.readLine()) != null) {
bw.write(str);
bw.newLine();
}
bw.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bw != null) {
bw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
e.printStackTrace();
} }
转换流——字节流和字符流之间的转换
很多时候我们使用转换流来处理文件乱码问题。实现编码和
解码的功能。
InputStreamReader:将InputStream转换为Reader
OutputStreamWriter:将Writer转换为OutputStream
对象流
ObjectInputStream和OjbectOutputSteam
它的强大之处就是可以把Java中的对象写入到数据源中,也能把对象从数据源中还原回来。不能序列化static和transient修
饰的成员变量
对象要想序列化,需要实现以下2个接口中的一个
?Serializable——需要写一个private static final long serialVersionUID;
?Externalizable
NIO
NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的(IO是面向流的)、基于通道的IO操作。NIO将以更加高效的方式进行文件的读写操作。
Java API中提供了两套NIO,一套是针对标准输入输出NIO,另一套就是网络编程NIO。
2.11 网络编程–暂跳
2.12 反射
public final Class getClass()–是object类的方法,获取当前对象的类
类加载过程
String name = “atguigu.java.Person";
Class clazz = null;
clazz = Class.forName(name);
Constructor con = clazz.getConstructor(String.class,Integer.class);
Person p2 = (Person) con.newInstance("Peter",20);
System.out.println(p2);
2.13 java新特性
Lambda表达式
Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。
函数式(Functional)接口
只包含一个抽象方法的接口,称为函数式接口。我们可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口。
40)]
NIO
NIO与原来的IO有同样的作用和目的,但是使用的方式完全不同,NIO支持面向缓冲区的(IO是面向流的)、基于通道的IO操作。NIO将以更加高效的方式进行文件的读写操作。
Java API中提供了两套NIO,一套是针对标准输入输出NIO,另一套就是网络编程NIO。
2.11 网络编程–暂跳
2.12 反射
public final Class getClass()–是object类的方法,获取当前对象的类
[外链图片转存中…(img-wzefGb9P-1638192359741)]
[外链图片转存中…(img-3OGMKin1-1638192359742)]-1622876677581.png)
[外链图片转存中…(img-ybFmfZmM-1638192359742)].png)
类加载过程
[外链图片转存中…(img-JJ47eOnv-1638192359744)]
[外链图片转存中…(img-xwpowspl-1638192359744)]
[外链图片转存中…(img-01h1dPkU-1638192359745)]
[外链图片转存中…(img-CScAgbdW-1638192359746)]
[外链图片转存中…(img-Do1NEs0I-1638192359747)]
[外链图片转存中…(img-aQw544xz-1638192359748)]
String name = “atguigu.java.Person";
Class clazz = null;
clazz = Class.forName(name);
Constructor con = clazz.getConstructor(String.class,Integer.class);
Person p2 = (Person) con.newInstance("Peter",20);
System.out.println(p2);
[外链图片转存中…(img-p2JsPYcq-1638192359749)]
[外链图片转存中…(img-JPze4K2k-1638192359749)]
2.13 java新特性
Lambda表达式
Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。
[外链图片转存中…(img-19A9aaIH-1638192359750)]
[外链图片转存中…(img-NReagMZL-1638192359751)]
函数式(Functional)接口
只包含一个抽象方法的接口,称为函数式接口。我们可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口。
|