首页 > 代码库 > Java-基础
Java-基础
一、基本数据类型
长度:整形:byte/short/int/long 1248,浮点型:float/double 4/8,字符char:2,boolean:1位,引用类型4个字节
1、byte short char 可自动转为int,long转int需要强制转型。
3、类型计算,以占用字节最多的为准,自动提升,但是int(double)*double 的结果仍是double,int(double*double)的结果才是int。
4、浮点运算往往产生误差,如果两个浮点数的误差能相互抵消,计算结果能保持正确。误差原因不是因为数的大小,而是因为数的精度,float精度在尾数23位,double在尾数52位,
5、定义的浮点数默认是double,如需指定float,需要在后面加上F。
6、浮点数计算,创建BigDecimal对象时,参数以String形式传入,不要以浮点型传入,否则传入的也是近似值。
7、不可变类(Immutable class)是指当创建了这个类的实例后,就不允许修改它的值了,基本类型的包装类、string都是不可变类。
8、显示定义构造方法后,编译器不会自动添加无参构造方法。
9、Object的hashcode是native方法,将对象的内存地址转换成一个整数。
10、父类有序列化,子类自动序列化,但是父类不能强制其所有子类都具有序列化的能力。如果父类没有序列化,子类要实现序列化,则要为其父类提供无参构造方法,同时在子类先序列化自身,再序列化父类的属性。
11、抽象类中的抽象方法(其前有 abstract 修饰)不能用 private、 static、 synchronized 和 native 等访问修饰符修饰。
12、switch语句是先计算season变量的排序值,然后与枚举常量的每个排序值进行对比的。
13、当枚举项数量小于等于64时,创建一个RegularEnumSet实例对象,大于64时则创建一个JumboEnumSet实例对象。
14、intanceof 只有左侧是右侧的指定类型的类型或者子类型,才返回true。
15、在Java里面只有基本类型和String(非 new String)是按值传递,其它的都是按引用传递。
16、注解:@Inherited 只是可控制对类名上注解是否可以被继承。方法:只有继承方法方可继承注解,重写的方法不能继承注解。
17、jdk代理类生成:在java.lang.reflect.Proxy包ProxyGenerator.generateProxyClass来为特定接口生成形式为“*$Proxy”的代理类的二进制字节流。
二、重载与重写。
重载实现的是编译时的多态性,重写实现的是运行时的多态性。
java里允许调用一个有返回值的方法的时候,不必将返回值赋给变量,这样JVM就不知道你调用的是有返回值的还是没返回值的,所以不能根据返回类型来区分重载。
关于重写:子类父类方法名保持一致;权限:子类>=父类,返回值、异常:子类<=父类。
四、内部类
用外围类创建内部类对象时,此内部类对象会秘密的捕获一个指向外围类的引用
匿名内部类没有构造方法,典型用法:
Thread t = new Thread(new Runnable() {
@Override
public void run() {
//匿名内部类用法,new 后面的Runnable是要实现的接口或者要继承的类。
}
}
}
});
集合类:
1、Collections.sort()排序算法:加强型归并排序。
2、在遍历collection的同时删除元素的时候:
请牢记,在从任何Collection(例如Map、Set或List)中删除对象时总要使用Iterator的remove方法,
也请谨记for-each循环只是标准Iterator代码标准用法之上的一种语法糖而已。
异常:
代码中加上try代码块就标志着运行时会有一个Throwable线程监视着该方法的运行,若出现异常,则交由异常逻辑处理。
1、throw抛出的是:Error、RuntimeException或它们的子类,函数上可以不用声明,编译仍能通过,但在运行时会被系统抛出;否则必须要在函数上声明throws,或者进行try处理;仅当显试抛出了异常,该方法的调用者才必须处理或者重新抛出该异常。
2、程序会在throw语句后立即终止,它后面的语句执行不到(除了finally块)。
3、throw要么和try-catch-finally语句配套使用,要么与throws配套使用。谁调用,从里向外寻找含有与其匹配的catch子句的try块。
4、没有找到匹配的catch语句块时,此异常将会抛给JVM处理,finally语句块里的会被执行,但finally语句块后的语句不会被执行。
5、如果finally块中包含了return语句,即使前面的catch块重新抛出了异常,调用该方法的语句也不会获得catch块重新抛出的异常,而是会得到finally块的返回值,并且不会捕获异常。
6、注意finally和return,只要finally里没有return,只要没有异常,返回值全部都是第一个return的,放到栈缓存里了。finally执行完毕后该方法已经有返回值了,后续代码就不会再执行了。
泛型:
1、泛型是在编译之前对类型进行约束,是源码级别上,在字节码中不存在泛型信息(实际上通过反射可以获取到),效率不受影响,这个过程称为类型擦除。
2、通配符?表示类型不定,使用时确定类型。用在声明变量或声明方法上,不能声明类,如class Father<?> 通配符变量不能被使用。? extends 表示<=父类,? super 表示>=自身。
3、泛型不能用在静态属性或方法上,所以在接口类中,泛型只能在方法(默认abstract)中使用,因为接口的属性默认为static final。
interface I<T>{
定义:T t;//报错:Cannot make a static reference to the non-static type T
4、泛型方法:只能在返回类型前面,并且只能访问对象信息,不能修改信息,因为T还未确定。
public static <T> void fun(T t){
System.out.println(t.getClass());
}
6、泛型在类继承的用法:
父类要么做擦除,要么泛型全部写上,不可少写,也不可多写,
取决于父类是否擦除,如果父类擦除,子类随便泛型,多少个都行。
如果父类没擦除,子类写的泛型不能比父类少。
定义class Father<T,T1>
class Child3<T,T1,T3> extends Father
Child3的泛型随便写多少个,因为父类泛型擦除了,但是下面:
class Child1<T,T1> extends Father<T,T1>
class Child2<T2, T, T3, T5, T6> extends Father<T6,T2>
Child1 必须至少写和Father一样的,顺序无关。
属性随位置而定,在父类中,随父类,在子类中,随子类。方法全部从父类而定。
7、泛型没有多态,但是Father<Object, Integer> f = new Child1<Integer, Object>();是对的。
8、泛型没有数组,可以声明数组,但是不能被实例化。报错Cannot create a generic array 。
9、泛型结构只参与“读”操作则限定上界(extends关键字),只参与“写”操作则限定下界(使用super关键字),Java的泛型是不支持协变和逆变的,只是能够实现协变和逆变。
IO:
判断文件是否为空,调用File.length()。
excel、word、pdf不属于纯文本文件,包含了很多格式信息,使用字节流读取会出现乱码,对这类文件需要使用第三方jar包。
InputStreamReader:字节流->字符流,一个字符等于两个字节,注意编码格式,默认操作系统字符集,否则乱码。
使用BufferReader包装InputStreamReader,提高效率。
OutStreamWriter:字符流转字节流,调用write()方法,使用字符编码转换器,在写入输出流之前,字节会在缓冲区缓冲,使用BufferWriter包装OutStreamWriter避免频繁调用转换器。
NIO基于Buffer进行高效io操作,Buffer是连续的堆外空间,由native代码实现,操作系统可以直接与缓冲区交互,java程序只需要完成对缓冲区读写,后续操作交给操作系统完成。通过Channel,java更好的与操作系统IO服务结合起来,充分利用Buffer缓冲区,Channel不是纯java实现,有native代码
支持NIO操作的io类有FileInputStream、FileOutputStream、RandomAccessFile
NIO是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。
通道中的数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入
缓冲区本质上是一块可以写入数据,然后可以从中读取数据的内存。这块内存被包装成NIO Buffer对象
文件读写乱码:编码、解码字符集不一致,API使用不当,因为一个中文需要两个字节,InputStream是以字节为单位读取,将中文拆成两个字节分两次读取。
其它:
本文出自 “浅谈技术” 博客,请务必保留此出处http://netpeak.blog.51cto.com/1135737/1895387
Java-基础