JAVA 一步一步向上爬

时间:2023-01-17 20:39:58

Java分为基本数据类型和引用数据类型(类、接口、数组)

Integer.MAX_VALUE

浮点型默认为double

java采用Unicode char为两个字节 Unicode为每一个字符定制了唯一的值 任何平台语言程序都可以放心使用

逻辑运算符 &AND与 &&短路与 |OR或 ||短路或

<<无符号左移位 >>>无符号右移位(0填充) >>有符号右移位

表示负数的三种方式 原码补码反码 补码=反码+1

程序的结构:顺序结构、选择结构、循环结构

数据类型 数组名[][] ={{第一行初值},{第二行初值}....}

main方法直接调用的方法要是public static

定义类时 全部单词首字母必须大写 定义方法时首字母小写之后每个单词首字母大写

方法的重载就是方法的名称相同但参数的类型和个数不同

Arrays.sort(数组名) 会改变原数组

JAVA中的多态一种是方法重载一种是对象多态 (根据函数的不同父类可化身不同的子类)

所有的对象名称都在栈内存中保存而对象的具体内容则保存在对应的堆内存中,必须用new关键字才能开辟堆内存 栈中存放的是堆空间的地址

封装性可防止随意给属性赋值(违法的值) 而要通过setter去赋值 setter可以提供检查机制 从而确保了变量的安全

如果一个类中已经明确声明了一个构造方法 那么程序在编译时将不会再生成默认的构造方法

匿名对象就是没有明确给出名字的对象,一般匿名对象只使用一次,而且匿名对象只在堆内存中开辟空间,而不存在栈内存的引用 使用一次后就等待被GC回收

String 比较用equals方法 而==表示地址的比较

String 使用直接赋值(String str="123")只要以后声明的字符串内容相同,则不会再开辟新的内存空间!

String str=new String("123") 通过new实例化 一个字符串就是一个String类的匿名对象 而如果使用new不管如何都会开辟一个新的空间,但此时空间的内容还是123,所以这种方法实际上开辟了两个内存空间

字符串的内容一旦声明不可改变! 即堆内存中的字符串不会发生变化 而是会为修改后的字符串新开辟一个堆内存 然后再让引用指向新的内存而原来的堆内存不发生任何变化!

一个String对象内容的改变实际上是通过内存地址的断开-连接完成的,而本身的字符串内容并没有发生变化
String str="luyu";for(100次循环) str+="1993"; 这是性能很低的代码,字符串的指向要断开连接100次

String(char[]value) char[]toCharArray() String trim()//清除左右两端的空格 String toUpperCase() /toLowerCase() boolean equals(String str) equalsIgnoreCase(String str)

数组的长度arr.length 字符串的长度str.length()

所谓的引用传递就是指将堆内存空间的使用权交给多个栈内存空间

this 调用本类中的属性this.属性 调用构造方法this() 要放在构造函数的开始

使用一个类分别开辟堆栈内存 在堆内存中要保存对象的属性 每个对象有自己的属性 如果希望有些属性被所有对象共享则必须声明为static属性
static ->全局属性(静态属性)

JAVA主要存在四块内存空间 (1)栈内存空间:保存所有的对象名称(更准确的说是保存了引用的堆内存空间的地址)(2)堆内存空间:保存每个对象的具体属性内容(3)全局数据区:保存static类型的属性(4)保存所有的方法定义

非static声明的方法可以去调用static声明的属性或方法(隐含this指针而this可以调用静态方法和属性)反之,static方法无法调用非static的方法和属性(无this指针)或者换一种理解方式 static类型的方法在对象未被实例化时就可以被类名调用,而非static程序中所有的属性和方法必须在对象开辟堆内存之后才能调用

所谓的代码块是指使用{}包围起来的一段代码,根据位置不同,代码块可以分为普通代码块(直接在方法或者语句中定义的代码块),构造块(直接写在类中的代码块,构造块优于构造方法执行,并且每次实例化对象时都会执行构造块中的代码,会执行多次),静态代码块(优于主方法执行,而且在类中定义的静态代码块会优于构造块执行,无论有多少对象产生,静态代码块只执行一次),同步代码块四种

私有化的构造方法,在同一个类中的时候可以new新的对象,而在其他类中则无法实例化对象,但是可以在本类中构造好,再想办法将实例传出即可
class Singleton{private static Singleton instance=new Singleton();
private Singleton(){}
public static Singleton getInstance(){return instance;}
}
public class Test(){
public static void main(String args[]){
Singleton s1=Singleton.getInstance();
Singleton s2=Singleton.getInstance();
Singleton s3=Singleton.getInstance();
}
}
虽然声明了三个Singleton对象但是实际上所有的对象都只使用instance引用,不管外面如何使用,最终结果也只是有一个实例化对象存在,在设计模式中将这样的设计成为单例设计模式,该类永远只会有一个实例化对象存在。

内部类的唯一好处就是可以方便地访问外部类中的私有属性 在其他外部类访问内部类 外部类.内部类 内部类对象=外部类实例.new 内部类();

方法中定义的内部类无法访问方法中的普通参数,要想被内部类访问必须加上final关键字但是可以访问方法所在的类中的属性

JAVA只允许多层继承但是不能多重继承 在继承时子类无法访问父类中的私有成员

子类对象在实例化之前必须首先调用父类中的构造方法后再调用子类自己的构造方法

子类可以直接使用super()调用父类中的无参构造

方法覆写:子类定义了与父类同名的方法,被子类覆写的方法不能拥有比父类方法更加严格的访问权限 如果要在子类的方法中访问父类的方法,则用super关键字即可 super.方法()

方法重载(Overloading)和方法覆写(Overriding)的区别
重载:方法名称相同,参数类型或者个数不同 对权限没有要求 且发生在一个类中
覆写:方法名称、参数类型、返回值类型全部相同 被覆写方法不能有更严格的权限 发生在继承类中

this和super的区别
this:访问本类的属性,如果本类中没有此属性,则从父类中继续查找 访问本类中的方法,如果本类中没有此方法,则从父类中积雪查找 调用本地构造,必须放在构造方法的首行 表示当前对象
super:访问父类中的属性 直接访问父类中的方法 调用父类构造,必须放在子类构造方法的首行 并不能表示当前的父类对象

使用final声明的类不能有子类 声明的方法不能被子类所覆写 声明的变量即成为常量,常量不可以修改 使用final声明变量时要求全部字母大写 如果一个程序中的变量使用public static final声明则此变量成为全局常量

一种类专门用来当做父类,这种类称为抽象类,抽象类的作用类似模板其目的是主要设计者依据它的格式来修改并创建新的类,但是并不能直接由抽象类创建对象,只能通过抽象类派生出新的类,再由它来创建对象。

包含一个抽象方法的类必须是抽象类 抽象类和抽象方法都要使用abstract声明 抽象方法只需声明而不需要实现 抽象类必须被子继承,子类(非抽象类)必须覆写抽象类中的全部抽象方法 抽象方法中没有方法体 抽象类的定义只是比普通类多了一些抽象方法

接口可以被理解为一种特殊的类,它由全局常量和公共的抽象方法所组成 接口中方法永远是public abstract(可省略) 属性永远是public static final(可省略)

JAVA中允许一个抽象类实现多个接口 并且无需实现接口中的方法 交由正常继承抽象类的类去实现

JAVA中一个接口是不允许继承抽象类的,但是允许一个接口继承多个接口(唯一的多重继承) interface 子接口 extends 父接口A,父接口B,...

如果对象发生了向上转型关系后,所调用的方法一定是被子类覆写过的方法,但转型后无法调用子类中有而父类中没有的方法

在进行对象的向下转型前,必须首先发生对象向上转型,否则将出现对象转换异常,eg:A a=new A();B b=(B)a;程序会报错,此时B继承自A。而要改为 A a=new B();B b=(B)a在进行向下转型关系前最好先进行判断后再执行 即:对象 instanceof 类名

JAVA中可以通过对象的多态性为抽象类和接口实例化,这样再使用抽象类和接口时即可调用本子类中所覆写过的方法。

适配器设计模式 如果一个类要实现一个接口 则必须覆写此接口中的全部抽象方法,那么如果并不想实现所有方法,则会比较麻烦,此时可以将一个接口被一个抽象类实现(此抽象类通常称为适配器类),并在此抽象类中实现若干方法(方法体为空)(要全部实现接口中的方法,方法体可以为空,否则子类必须要实现未实现的方法),则以后的子类直接继承此抽象类,就可以有选择的覆写所需要的方法了!

在一个抽象类中可以定义多个接口或抽象类,在一个接口中也可以定义多个抽象类或接口

在类的设计中一定要明确一个原则,一个类不要去继承一个已经实现好的类,只能继承抽象类或实现接口,如果接口和抽象类都可以使用,那么优先使用接口,避免多继承局限。接口不能继承一个类!!!但是依然是Object类的子类

如果接口的实现类只使用一次,那么没有必要单独定义一个子类,此时就可以使用匿名内部类完成,fun(接口A的一个实例) 此时不想定义一个子类,还想把A的实例传过去,但是接口本身是不能直接进行实例化的,那么可以这么做fun(new A(){接口A的实现方法//实现接口中的抽象方法})

因为程序中加入了异常处理代码,所以当有异常发生后,整个程序也并不会因为异常的产生而中断执行

Throwable的两个子类Exception(表示程序中出现的问题可以直接使用try catch处理)和Error(JVM错误,程序中无法处理)

在定义一个方法时可以使用throws关键字,表示此方法不处理异常,而交给方法的调用处进行处理 若主方法再向上抛异常,则只能将异常抛给JVM进行处理。而throw关键字可以直接抛出一个异常,抛出时直接抛出异常类的实例化对象即可
Exception在程序中必须使用try...catch进行处理

RuntimeException(是Exception的子类)可以不使用try...catch处理,但是如果有异常发生,则异常将由JVM进行处理

两种导入方式import 包.* /包.具体类 性能是完全相同的所以推荐使用前者

如果一个类中的方法全部都是static声明的静态方法,则在导入时就可以直接使用import static 包名.*,所有静态方法可以直接在该类中使用,而不再需要使用类.静态方法()的形式

protected的类可以被同一包中的类以及不同包中的子类所访问比default更为开放

命名规范类:所有单词的首字母大写 TestJava 方法第一个单词的首字母小写,之后每个单词的首字母大写 如getInfo() 属性同上 如studentName

JAVA中多线程通过两种手段实现,一种是继承Thread类(也是Runnable接口的子类),另一种是实现Runnable接口

继承Thread类,必须明确覆写Thread类中的run()方法 并且调用时要用对象1.start();对象2.start();此时两个线程才会交错进行 如果对象1.run() 对象2.run()这样是无法交替进行的 会先等待第一句再执行第二句 注:线程的运行需要本机操作系统的支持 所以无法直接调用子类方法run() 如果多次调用一个对象的start方法 会抛出IllegalThreadStateException异常

实现Runnable接口,接口只定义了一个抽象方法 public void run();实现了Runnable接口的线程类,此时还是要依靠Thread类完成启动,在Thread类中提供了Thread(Runnable target)和public Thread(Runnable target,String name)两个构造方法 MyThread m1=new MyThread(); //MyThread implements Runnable Thread t1=new Thread(m1);t1.start();两种实现无论哪种方式,最终都必须依靠Thread类才能启动多线程

如果一个类继承Thread类,则不适合于多个线程共享资源,而实现了Runnable接口就可以方便地实现资源的共享,在开发中建议使用Runnable接口实现多线程!

调用sleep suspend wait方法可以使线程进入堵塞状态

每次JAVA程序运行至少启动两个线程,一个是main线程,一个是垃圾收集线程

主线程有可能比其他线程先执行完,此时其他线程不会受到任何影响,并不会随着主线程的结束而结束

在线程的操作中可以使用join()方法让一个线程强制运行,线程强制运行期间,其他线程无法运行,必须等待此线程完成之后才可以继续执行。

线程有三种优先级 MIN PRIORITY / NORM PRIORITY / MAX PRIORITY main方法的优先级是NORM PRIORITY

解决资源共享的同步操作,可以使用同步代码块和同步方法两种方式完成,所谓同步就是指多个操作在同一个时间段内只能有一个线程运行,其他线程要等待此线程完成之后才可以继续执行。

同步代码块 synchronized(同步对象){需要同步的代码;} 一般同步对象设为this即当前对象

同步方法 synchronized 方法返回值 方法名称(参数列表){}

JAVA方法定义的完整格式 访问权限+final+static+synchronized+返回值类型+方法名称(参数类型 参数名称,...)throws Exception1,Exception2{}

过多的同步会造成死锁的现象 synchronized(对象1){synchronized(对象2)} 和 synchronized(对象2){synchronized(对象1)} 二者同时执行就会出现死锁的情况第一句话等待对象2 第二句话等待对象1 两个线程都在等待对方的执行完成

Object是所有类的父类 其中一些方法对线程操作有所支持wait()线程等待 notify()唤醒第一个等待的线程 notifyAll()唤醒全部等待的线程,优先执行优先级高的线程

泛型可以解决数据类型的安全性问题,在类声明时通过一个标识表示类中某个属性的类型或者某个方法的返回值及参数类型。在类实例化时只要指定好需要的类型即可。class 类名称<泛型类型标识1,泛型类型标识2>{} 类名称<具体类> 对象名称=new 类名称<>();
泛型的上限 声明对象:类名称 <? entends 类>对象名称 定义类:[访问权限]类名称<泛型标识 extends 类>
泛型的下限 声明对象:类名称 <? super类>对象名称 定义类:[访问权限]类名称<泛型标识 super 类>{}

一个类的子类可以通过对象多态性为其父类实例化,但是在泛型操作中,子类的泛型类型是无法使用父类的泛型类型接收的 例如Info<String>不能使用Info<Object>接收 可以使用Info<?>接收

字符串反转 StringBuffer str=new StringBuffer(oldstr);oldstr=str.reverse().toString();从而完成了字符串反转。对于频繁修改字符串内容的地方,最好使用StringBuffer完成

Runtime类本身的构造方法是私有化的(单例设计) Runtime表示的是每一个JVM实例,常用方法getRuntime() freeMemory()//返回虚拟机中的空闲内存量 maxMemory//返回JVM的最大内存量 gc()//运行垃圾回收释放空间 exec//执行本机命令 返回值为Process类 表示当前打开的进程

实现国际化程序要靠Locale类以及属性文件(.properties 文件中内容为key=value格式)和ResourceBundle类(访问属性文件)的支持 和MeessageFormat类(格式化资源文件的占位字符串) 属性文件可以用类来替代

这三个类的具体操作流程为通过Locale类所指定的区域码,然后ResourceBundle根据Locale类所指定的区域码找到相应的资源文件,如果资源文件中存在动态文本,则使用MessageFormat进行格式化

System类也有gc方法用于释放内存,但是如果一个对象被回收之前要进行某些操作,则要覆写Object类中的finalize()方法

对大数进行操作BigInteger BigInteger(String val) add(BigInteger) substract() multiply() divide() max() min() divideAndReminder()//返回一个BigInteger[] 第一个元素为除法的商 第二个元素为除法的余数

如果需要精确计算的结果 必须使用BigDecimal 也可以进行大数操作 BigDecimal(double/int/String val) add substract multiply divide

对象克隆技术需要对象所在的类实现Cloneable接口 必须覆写Object类中的clone()方法//一般为public 具体的克隆方法的实现还是在Object中 在覆写时只需要调用Object类中的clone方法即可完成操作 public Object clone() throws CloneNotSupprotedException{return super.clone();}

Arrays类的常用方法 equals(int[]a,int[]b) fill(int[]a,int val) sort(int[]a) binarySearch(int[]a//sorted arr,int key) toString(int[] a)

Arrays类如果想对Object数组进行排序,则对象所在的类必须实现Comparable接口,此接口就是用于指定对象排序规则的 public interface Compareble<T>{public int compareTo(T o);} 1:> -1:< 0:==

如果一个类已经开发完成,但是此类建立初期并没有实现Compareble接口,此时肯定无法进行对象排序操作,此时可以使用Comparator接口 public interface Comparator<T>{public int compare(T o1,T o2)//返回值仍然是1 0 -1;boolean equals(Object obj);}此时需要单独定义一个比较器的比较规则类才可以完成数组排序Arrays.sort(T[] a, Comparator<? super T> c) c就是重新定义的规则类 由于Object中定义过equals所以实现Comparator接口的类可以不去覆写equals

观察者模式实现 被观察的类必须继承Observable类 每一个观察者要实现Observer接口

正则表达式操作类是需要通过Pattern和Matcher两个类完成操作的 boolean flag=Pattern.compile("正则表达式").matcher(str).matches())

Pattern方法 static Pattern compile() Matcher matcher() split() Matcher方法 boolean matches() replaceAll()

String类对正则表达式的支持 boolean matches(String regex) String replaceAll(String regex,String replacement) String[] split(String regex) 建议直接使用String中的方法 这样比较方便

定时调度Timer类其中schedule方法执行时间间隔永远是固定的,即使出现了延迟,而schedAtFixedRate可根据出现延迟的时间自动调整下次间隔的执行时间

TimerTask用于指定任务,该类是一个抽象方法,子类要继承该类并且覆写run方法

在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据时要使用输入流读取数据,当程序需要将一些数据保存起来时,就要使用输出流。

JAVA中流的操作主要有字节流(byte)、字符流(可以直接操作字符串,无需将字符串转为byte数组,读取的时候存到char[]中而不是byte[]中)两大类,在字节流中输出数据主要使用OutputStream类完成,输入使用的是InputStream类,在字符流中输出主要使用Writer类输入使用Reader类完成。

字节流在操作时本身不会用到缓冲区,是文件本身直接操作的,而字符流操作时使用了缓冲区,通过缓冲区再操作文件。关闭字符流才会强制性的将缓冲区中的内容输出,如果没有关闭,则缓冲区中的内容是无法输出的。如果想在不关闭时也将字符流的内容全部输出,则可以使用Writer类中的flush()方法完成。

使用字节流更好,所有文件在硬盘或者在传输中都是以字节的方式进行的,包括图片都是按字节的方式存储的,所以字节流使用更广泛

OutputStreamWriter 将输出的字符流变为字节流 InputStreamReader 将输入的字节流变为字符流

管道流的主要作用是可以进行两个线程间的通信,PipedOutputStream PipedInputStream

打印流PrintStream和PrintWriter

System类对IO的支持 public static final PrintStream out 对应系统标准输出一般是显示器 public static final InputStream in对应标准输入,一般是键盘

System.err和System.out都可以输出错误信息,一般来讲.out是将信息显示给用户看,是正常的信息显示,而.err的信息是不希望用户看到的,会直接在后台打印,是专门显示错误的。

一个中文字符等于两个字节(byte)如果byte为奇数那么可能会出现乱码的情况

可以通过System类提供的重定向方法来对输入/输出重定向 setOut setErr serIn

Scanner类可以接收任意的输入流 Scanner(File f)//从文件中接收内容 Scanner(InputStream s)//从指定的字节输入流中接收内容 hasNext(Pattern pattern) hasNextInt() hasNextFloat() next next(Pattern pattern) nextInt() nextFloat()

乱码的产生就有一个原因,即输出内容的编码(程序指定)与接收内容的编码(本机环境默认)不一致

对象序列化就是把一个对象变成二进制的数据流的一种方法,可以方便的实现对象的传输或存储,如果一个类的对象想被序列化,则对象所在的类必须实现java.io.Serializable接口 此接口是一个标识接口,标识一个类具备了被序列化的能力。如果要完成对象传输还必须依靠对象输出流ObjectOutputStream和对象输入流ObjectInputStream 使用对象输出流输出序列化对象的步骤成为序列化,而使用对象输入流读入对象的过程成为反序列化

在序列化后只有属性被被序列化了 每个对象都有相同的方法,但是每个对象的属性不一定相同,也就是说,对象保存的只有属性信息,只有属性被序列化 如果用户想根据自己的需求选择被序列化的属性 那么要使用Externalizable接口

当使用Serializable接口实现序列化操作时,如果一个对象中的某个属性不希望被序列化,则可以使用transient关键字进行声明。

使用类集接口时,如果没有指定泛型,会出现警告信息,此时,泛型将被擦除而全部使用Object接收

Collection 常用方法 add addAll clear contains containsAll equals hashCode isEmpty remove iterator size toArray//Object[] toArray(T[]a) //指定类型

Collection ->List Set Queue SortedSet Map->SortedMap //以及Iterator这些都是接口!

LinkedList 实现了list以及Queue的接口 方法addFirst(E) addLast(E) removeFirst() removeLast() 也可以调用Queue中的方法 element() 找到链表的表头 offer(E)将指定元素增加到链表的结尾 E peek()找到但并不删除链表的头 E poll()找到并删除此链表的头 E remove()找到并移除链表的头

TreeSet中的每个对象所在的类都必须实现Comparable接口才可以正常使用!!!此时并非真正去除重复元素 (需要对每个属性进行判断,如果属性比较多则很难判断是不是同一个对象)

想真正去除重复元素:每个对象所在的类必须覆写Object类中的equals方法以及hashCode方法

TreeSet常用方法add addAll clear clone comparator contains first last remove size iterator

Iterator接口中的常用方法hasNext() next() remove()

List<String> all=new ArrayList<String>(); Iterator<String> iter=all.iterator();

如果在使用Iterator输出时集合自己调用了删除方法,则迭代过程会停止后序元素无法访问

Map接口的常用方法 clear containsKey(Obj key) containsValue(Obj value) Set<Map.Entry<K,V>> entrySet() equals(Obj o) get(Obj key) isEmpty() Set<K> keySet()

V put(K key,V value) remove(Obj o) size() Collection<V>values()

HashMap:采用异步处理方式,性能高,属于非线程安全的操作类

Hashtable:采用同步处理方式,性能较低,属于线程安全的操作类

TreeMap的key如果是自定义的类需要实现Comparable接口

输出Map:Set<Map.Entry<String,String>> allSet=map.entrySet(); Iterator<Map.Entry<String,String>> iter=allSet.iterator();while(iter.hasNext()){Map.Entry<String,String>me=iter.next();System.out.pringln(me.getKey()+me.getValue());}或者使用foreach遍历Set<>也可

如果Map中的key是一个自定义类的对象,根据key查找时只有确切知道key的引用地址才能找到value,但是大多数情况是根据一个匿名对象去查找,此时该类需要覆写equals和hashCode方法

IdentityHashMap只要两个key地址不相等就表示不是重复的key new两次同一个对象二者地址是不同的 此时可以作为两个key

集合工具类Collections max(Collection o) min(Collection o) reverse(List list) sort(List list) repalceAll()

如果要通过一个对象找到一个类的名称,此时就需要用到反射机制;所有类的对象都是Class类的实例

Class类本身没有定义任何构造方法,要使用有三种方法实例化对象,Class.forName("包.类名") new X().getClass() X.class

Class类在开发中最常见的用法就是实例化对象的操作,通过一个给定的字符串来实例化一个类的对象,通过newInstance()方法,但是必须要保证被实例化的类中存在一个无参构造方法!在进行反射开发时类中一定要保留无参构造方法。 如果没有无参构造函数,也可以通过返回类的所有构造方法 Constructor<?> cons[]=null;cons=c.getConstructors(); per=(Person)cons[0].newInstance("123","123");这样去实例化对象 还是建议在类中留一个无参构造方法

反射除了可以取得一个类的完整结构外,还可以调用类中的指定方法或指定属性,并且可以通过反射完成对数组的操作。

Method met=c1.getMethod("方法名称",String.class,int.class);String rv=(String)met.invoke(c1.newInstance(),"李兴华",30); //Method.invoke(实例,参数)

类的生命周期,类编译完成后,要通过JVM装载、连接、初始化三个步骤,类的装载就是通过类加载器把. class二进制文件装入JVM的方法区,并在堆区创建描述该类的java.lang.Class对象,用来封装数据,同一个类只会被JVM加载一次;链接就是把二进制数据组装成可以运行的状态,分为校验、准备、解析三个步骤。校验用来确认此二进制文件是否适合当前的JVM版本;准备就是为静态成员分配内存空间,并设置默认值;解析指的是转换常量池中的代码引用为直接引用的过程,知道所有的符号引用都可被运行程序使用。完成之后,类型即可初始化,初始化之后类的对象就可以正常使用,对象不再使用之后,将被垃圾回收,释放空间。当没有任何引用指向class对象时将会被卸载,结束类的生命周期。

通过反射,可以做到增加子类,而不必修改工厂类//之前要通过字符串去判断然后去实例化,现在提供统一的接口,使用反射,方便很多

系统内建了如下三个Annotation(注释) @Override:覆写的Annotation 只能在方法上应用 防止覆写时方法名称出错?@Deprecated:不赞成使用的Annotation 用来声明一个不建议使用的方法 编译时会出现警告,但是程序可以正常执行,除了用在方法上声明也可以在类中进行声明@Suppress Warnings压制安全警告的Annotation eg:@SuppressWarnings({"unchecked"//未指定泛型,"deprecation"//不建议警告 })

使用@Documented注释后,此Annotation在生成javadoc时就可以加入类或方法的一些说明信息,这样可以便于用户了解类或方法的作用 JAVA中使用@interface定义一个Annotation

newIO采用面向块的概念而不是最初的面向流,这意味着在尽可能的情况下IO操作以大的数据块为单位进行,而不是一次一个字节或者字符的进行 NIO中所有的操作都要使用到缓冲区处理,每一种基本数据类型都有一种对应的缓冲区操作类

JAVA中访问文件内容的4种方法 RandomAccessFile随机读取数据,此种访问速度较慢;FileInputStream文件输入流,使用此种方式速度较慢 缓冲读取(例BufferedReader)使用此种方式访问速度较快 内存映射(MappedByteBuffer) 使用此种方式读取速度最快 读取数据很快但是写入数据就可能非常危险,可能会修改磁盘上的具体文件

文件锁:当一个线程将文件锁定后,其他线程无法操作此文件,文件锁方式有两种 共享锁:允许多个线程进行文件的读取 独占锁:只允许一个线程进行文件的读/写

Charset类负责处理编码的问题 包括解码和编码 通过解码器可以方便读取各个平台上不同的编码数据,之后再通过编码器将程序的内容以正确的编码输出

JDBC(Java Database Connectivity)