JAVA细节上的特别之处

来源:互联网 发布:网络热词排行榜2017 编辑:程序博客网 时间:2024/04/29 04:00

JAVA有吸收C,C++的优点,同时某些方面又添加了自己的特点

1关于注释

除了单行,多行注释,又添加了

文档注释

利用javadoc可以生成相应的API文档

2java默认UNICODE字符集,可以用中文日文表示标识符

3goto,const是保留字,true,false,null是直接量,再加上48个关键字,都不可以作为标识符

4基本数据类型有boolean,byte,char,short,int,long,float,double,此外其他都是引用类型

JAVA7新增加了二进制数字类型,例子int binNum=0B10101011;// 0b或0B

JAVA7用下划线可以分隔数字,例子double pi=3.14_15_92_65_36;// 只是为了防止看错

5移位运算符添加>>>无符号右移

>>是算术移位,>>>是逻辑移位

6关键字instanceof

7switch在JAVA7中,新增了String类型

8break,continue可以用标签(类似goto功能的标号)进行外层循环的跳出

9数组类型

JAVA5增加了foreach的循环,例子for(Class o:oSet)// oSet是数组,array,set等集合,其中o只是开辟的临时变量,并不是数组中真正成员,在循环体中赋值要注意是否有效

10java.util.Arrays类

binarySearch

copyOf

equals

fill

sort

System.arraycopy

11初始化是创建一种引用,new后将引用与新对象进行关联;

基本类型对应的包装类型,作为类中成员变量时的初始化默认值(而局部变量中的默认值是任意值,这与C一致)
boolean Boolean
false
char Character
\u0000(null)
byte Byte  0
short Short 0
int Integer 0

long Long  0L

float Float 0.0f
double Double 0.0d
void Void

在创建数组对象时默认创建引用数组,并初始化为null(与C++的区别,C++会执行默认构造函数,创建在栈空间中);

12JAVA有类似C中的作用域屏蔽变量的概念(实际上屏也是因为默认省略了成员变量前的this或static),最好用对象将其区分开,static,this修改对象

13package名类似于域名,只不过是反转过来使用的(例如com,edu,org,net)

13,JAVA没有sizeof(因为不需要底层移植了)

14非零值无法表示布尔true(与C++不同),因为JAVA中的数值与boolean不能转换,boolean可以用"true"字符串来转换

15this的使用,static成员的使用

16JAVA方法中参数传递都是值类型,但由于非基本类型都是引用类型,所以值传递过来,形参=复制值生成新的引用,形参与实参操作的都是同一对象,所以修改形参的属性将会影响调用方法原形参的属性,但将实参=null,并不影响形参,想想看为什么!

17可变个数形参,例子void test(int a,String ... params){}//只能是形参列表最后一个,只能有一个,传递时可以传入数组

18对象可以访问static成员(即使置为null后),但最好直接用类名来操作static,概念和可读性都佳

19访问控制符级别private>default>protected>public

20import,JAVA默认导入了java.lang下的所有类,import static可以导入static类或成员

21常用package

java.lang:String,Math,System,Thread

java.util:Arrays,List,Set

java.net

java.io

java.text

java.sql

22构造函数中用this(param,...)调用另外一个构造函数

23JAVA实行单继承extends,只能直接继承一个父类,所有类都派生于java.lang.Object

24JAVA中的函数无法继承,只能显示的super.constructer();

25JAVA初始化块,

初始化块与成员的默认值先后是由书写顺序决定,

初始化顺序是:基类static初始化块,类static初始化块(static只在加载类时执行一次),基类初始化块,基类构造,类初始化块,类构造

26基本数据类型的包装类,对值的判断应该用compare方法,==有时会不一置

27final成员,

系统不会隐式初始化,程序员初始化后其值不可改变(只能赋值一次),修饰形参不能赋值(可以理解为C中的const)

修改引用类型时,引用变量可以修改其对象数据,但不能指向其他对象了

28final变量在定义时指定初化值,且编译时就能计算确定下来(表达式中没有调用类方法),则所修饰变量将会转化为常量

final方法可以重载,子类不能重写父类的final方法,这与子类定义父类同名的private方法区别:后者是新写了一个名字相同的方法,前者编译器不允许,private final执行private原理

final类无法继承

29abstract抽象类,不能实例化,可以理解成子类的模板,设计的雏形

abstract抽象方法,子类必须得重写(除非又是一个抽象子类)

可以有成员变量,可以有成员方法,可以有static方法和常量,可以有构造和初始化块

abstract和final,static,private不能同时用

30interface接口,不能包含普通方法,所有方法都是抽象方法,可以理解成子类的规范,系统的纲目

接口可以多继承,只包含构造和初始化块,只能有常量成员public static final,只能有抽象方法public abstract,内部类,枚举public static 

31implements可以多实现

32内部类

静态内部类:外部类加载时,静态内部类不会被立即加载(可以借此实现单例),内部方法不能访问外部类对象成员(只能访问静态成员方法)

非静态内部类:利用这个实现JAVA中的闭包,必须由外部类对象来创建,不能有静态成员,静态块,静态方法

局部内部类::不能使用static修饰

匿名内部类:必须继承一个父类或实现一个接口(最多一个),创建后,类定义生成一个实例,同时类定义消失,不可复用;访问外部类的成员,必须被final修饰

33枚举类

enum,每一个枚举量就是一个实例

含有抽象方法的enum类会自动提升为抽象类,同时在枚举值中必须实现抽象方法(类似匿名内部类的实现,直接产生实例)

非抽象枚举类默认被final修饰,因此不能派生子类

34GC

GC负责堆中不再引用的空间回收,IO资源不处理

无法精确控制

GC执行之前会调用finalize()

引用变量三种状态

可达,可恢复,不可达

System.gc();  Runtime.getRuntime().gc();

System.runFinalization();//强制执行finalize(),不建议使用

35软,弱,虚引用

强,默认引用

软,内存不足时会回收

弱,GC时可能会回收

虚,只有虚引用时,几乎就是没引用,必须和引用队列联合使用(通过检查与虚引用关联的引用队列中是否已经包含了该虚引用,从而了解虚引用的对象是否即将被回收)

java.lang.ref

recreateIt()

36Scanner获得键盘输入:hasNextXXX,nextXXX

37BufferedReader   new BufferedReader(new InputStreamReader(System.in));//

38System: getenv,getProperties,currentTimeMills(),nanoTime(),in,out,err,identityHashCode,

39Properties

40Runtime:getRuntime(),exec

41Object:equals,finalize,getClass,hashCode,toString,clone(类似于浅拷贝),wait,notify,notifyAll

42Objects工具类,JAVA7添加,其大多方法是null指针安全

requireNonNull验证参数,不空返回参数,空则引发异常

43

String是不可变类

compareTo,返回字母差或长度差(前段串均一致的情况下)

StringBuffer线程安全

StringBuilder线程不安全

append,insert,replace,delete,reverse,length,setLength,capacity

44

Math

45

Random

ThreadLocalRandom是JAVA7添加的并发环境优化的随机数生成类,用current()获得对象

46BigDecimal为了防止精度丢失,不建议使用double数来创建对象,最好用String或BigDecimal.valueOf来创建,防止数在double参数赋值时会被改变值

47Calendar,getInstance()

注意add和roll的区别,前者带进位,后者不进位,进位过程中出现不合逻辑的日期(如每月天数不一致,月计算后就会造成日不合逻辑),日期将向修正到变化最小的值

setLenient设置是否宽容,true表示宽容,超过范围后将进位

set方法会延迟修改,延迟到下次get或add roll的时候

48TimeZone

49正则表达式:是一个用于匹配字符串的模板,利用这个模板可以匹配一批字符串

matches

replaceAll

replaceFirst

split

Pattern不可变类,Pattern.compile(regex);

Matcher,p.matcher(str);m.matches();

50

I18N与I10N

ResourceBundle

Locale

MessageFormat,NumberFormat,DateFormat

SimpleDateFormat

51集合类

Collection中保存的是引用,操作的是对象

Set不允许重复的容器,重复是指的equals,值相等,即使引用不等,也会add失败

Queue

List


Map

HashMap

TreeMap

HashTable


Iterator

迭代时传递的是元素的值,修改其变量并不能改变集合内的元素

迭代中不允许remove元素


HashSet是不允许hashCode重复的容器,值重复但hashCode不同可以add,但理论上重写应保证 值 与hashCode保持一致,

HashSet中添加可变对象注意,在修改该对象时可能造成hashCode改变为另外一个已有对象的hashCode,而导致HashSet无法定位准确的对象

LinkdedHashSet带有插入顺序的hashSet

TreeSet(SortedSet):如果添加对象集合到TreeSet,一定要实现该类的Comparable接口compareTo方法,因为没有默认规则,compareTo为0则无法添加,理论上重写应保证equals与compareTo保持一致

添加可变对象的问题与HashSet类似

EnumSet

上述Set都是线程不安全


List是有序,可重复,带有索引的集合,List判断对象相同的标准是equals

ListIterator,可以向前迭代previous

ArrayList,默认initialCapacity为10,如果确定要添加大量元素,可以ensureCapacity(minVal)一次性增加该值以减少扩充容量的性能损耗

相应地有trimToSize减少空间

线程不安全

注意Arrays.asList得到的ArrayList是内部类实例,不可变

子类LinkedList实现了List和Deque

Vector线程安全,但较古老不建议使用,有子类Stack


Queue

PriorityQueue

Deque其实现类有ArrayDeque ,LinkedList


Map// JAVA实际是先实现了所有的Map子类,然后包装成value都为null 的集合实现了Set集合类

Entry

HashMap, initialCapacity初始化容量loadFactor装载因子,

LinkedHashMap

SortedMap

TreeMap

WeakHashMap

IdentityHashMap要求两个key严格相等时才算相等(key1==key2)

Hashtable较古老,不建议使用,线程安全,不允许用null作key,value但HashMap允许


Properties是Hashtable的子类


Collections,操作集合的工具类,可以进行排序,查找,替换,

shuffle对List中元素随机排序

binarySearch

max

fill

frequency

indexOfSubList

replaceAll

同步控制Map m=Collection.synchronizedMap(new HashMap());

返回不可变集合emptyXxx();singletonXxx();unmodifiableXxx();


BitSet古老的集合

Enumeration古老的迭代器,类似Iterator,用来遍历古老的集合


52泛型

泛型T不同,仍然是同一个类,因为不能添加静态T成员,不能在静态方法中使用T参数,instanceof后不能用泛型类

类型通配符?

?表示容器中的泛型是各种泛型的父亲,用通配符作泛型参数的集合,不能修改其中的元素,因为不确定是什么类型的元素

? extends Class表示容器中的泛型是继承于Class的,也可以是Class本身,相当于设定上限

? extends Class & interface 设定多个上限或接口

static <T> void func(T[] a,Collection<T> c)泛型方法,与普通方法相比,多了类型形参的声明,<T>用尖括号,多个类型如<T,S>用逗号隔开,所有类型形参声明放在修饰符和返回值之间

泛型方法和通配符使用的区别

泛型方法允许类型形参被用来表示方法的一个或多个参数之间的类型依赖关系,或者方法返回值与参数之间的类型依赖关系,如果没有依赖,就不应该使用泛型方法,而使用通配符

通配符用于形参时,不可以向集合中添加元素,也不可以修改元素

通配符还可以在定义变量时表示类型,泛型方法只能在方法中显式声明

通配符在方法中声明类型相对经清晰和准确


泛型构造器

public <T> Class(T t)

{

}

new Class("abc");  // 隐式构造String

new <Integer> Class(123);// 显式构造Integer


? super Class// 通配符设定下限


类型擦除,当带有泛型信息的对象赋给没有泛型信息的变量时,尖括号的类型信息会被擦除,例如List<String>给List,会变成List<Object>

反过来赋则只是"未经检查的转换"


泛型与数组

数组元素不能包含类型变量或类型形参,除非是无上限的通配符,

但是可以声明,例如可以声明List<String>[]的数组,不能创建ArrayList<String>[10]的数组对象

也就是说不能利用泛型数组


53异常

try中是一局部块

catch按顺序捕捉,出现异常后,后面的将不再捕捉,因此先"小异常"再"大异常"(先子类异常再父类异常)

finally一定执行,异常中即使return也会执行finally,但如果用System.exit(1),则会跳过,

通常不要在finally中添加return或throw语句,因为这样会造成try,catch中的return ,throw失效,

JAVA7中添加了自动关闭资源的try语句

throws向上抛异常,子类方法抛出的异常应该是父类方法抛出的异常的子类或相同

自行抛出异常用throw,checked异常需要在try catch块或向上throws中,

而Runtime异常就不需要,更加灵活


54annotation


55

File类

deleteOnExit当虚拟机退出时执行删除

FilenameFilter接口

InputStream字节流

OutputStream

Reader字符流char(16位=两个字节)

Writer

FileInputStream

FileReader

ByteArrayInputStream

CharArrayReader

PipedInputStream

BufferedInputStream

BufferedReader

ObjectInputStream


RandomAccessFile,getFilePointer,seek,构造函数中的mode有r,rw,rws,rwd


Serializable序列化

反序列化时并没有调用构造器来生成对象

一个文件多次序列化,则反序列化的顺序应保持一致

序列化可变对象时,第二次写入改变的对象,将只输出原对象的序列化编号,也就是说再读取出来时,值始终保持第一次写入的状态

递归序列化

在关键字前增加transient可以不序列化此成员变量

自定义序列化方法writeObject,readObject,readObjectNoData //可以利用这点进行流加密解密

writeReplace序列化对象替换,readResolve读取,主要应用于单例类,枚举类的序列化

序列化的版本long serialVersionUID


56

Buffer,ByteBuffer,CharBuffer,MapedByteBuffer,通过allocate申请,allocateDirect可以申请直接ByteBuffer,性能更高,一般用于长期生存的Buffer

flip(),clear()

Channel只能与Buffer交互,没有构造器,是从InputStream类getChannel()获得,然后map()成为MappedByteBuffer后输出,或者重载read,write


57

Charset,forName(),encode(),类似String中的getByte(String charset)

CharsetEncoder,CharsetDecoder


58

FileLocak

从FileChannel从lock/tryLock获得文件锁,前者阻塞,后者非阻塞,release释放锁

共享锁,排他锁


59多线程

Thread,currentThread获取当前线程,Thread类不能共享数据,不能再继承其他类

Runnable接口,实现该接口的类,可以继承类,其同一对象可以在多个线程中同时运行,从而可以共享数据

JAVA5 新增Callable类似Runnable,用,FutureTask 包装Callable,然后放入Thread中运行,可以根据,FutureTask 对象.get()获得相应的返回值

sleep()进入阻塞,移植性比yield强

yield()进入就绪

start()进入就绪

stop()进入死亡(容易死锁)

resume()阻塞到就绪

suspend()运行到阻塞,(容易死锁)

isAlive()

join()等待join线程执行完


Daemon守护线程,在前台线程执行完后,后台线程会自动锁毁

setDaemon(true)

守护线程创建的依然是守护线程


子线程优先级与父线程优先级相同,默认情况下


Thread.sleep(1)的作用是将时间片让度给其他线程,用1ms的时间停止当前线程的执行,让CPU重新分配时间片


synchronized(obj)// 同步监视器

{

}

同步锁,obj一般是共享资源,设置临界区

同步方法的同步监视器是this


Object类

wait()方法会释放当前同步监视器synchronized的锁定

notify()

notifyAll()

这些操作类似操作系统概念中的PV锁同步操作顺序,LOCK类似PV锁共享资源


Lock接口,ReadWriteLock接口

ReentrantLock

Condition类似Object类中

Condition cond=lock.newCondition();

await

signal

signalAll

信号量操作


BlockingQueue

生产者向其装载数据,满时会阻塞

消费者取数据,空时会阻塞


ThreadGroup


Executors工厂类,线程池


ThreadLocal线程局部变量,为每个线程提供变量副本


ConcurrentHashMap高效并发的实现类

CopyOnWriteArrayList写操作靠复制数组,读操作很快


60网络操作

InetAddress

URLDecoder

URLConnection

ServerSocket

Socket,setSoTimeout是设定工作超时,socket.connect(ip,timeout)这里的timeout是连接超时

shutdownInput半关闭

shutdownOutput


DatagramSocket

receive(dp)

send(dp)

DatagramPacket

MulticastSocket用于接收的多播必须指定一个端口

joinGroup

leaveGroup

setTimeToLive(int ttl)//设置packet 可以经历多少个子网,0表示本机,1是局域网


Proxy

ProxySelector


61JAVA代码被编译成class,class或JAR或网络资源会被加载到JVM中形成java.lang.Class对象,在链接后才开始初始化,final常量仅作类似的宏替换,其相关代码并不会触发类的初始化

ClassLoader

loadClass并未初始化

forName初始化了

findClass

getParent返回父类加载器

getSystemClass

findLoadedClass

三种类加载器

Bootstrap非ClassLoader的子类,是JVM的一部分,不是JAVA实现的

Extension

System


加载机制

全盘负责

父类委托

缓存机制


URLClassLoader是扩展类加载器的父类


Class类

Class对象可以get获得Filed,Method,Constructer,Annotation,Class(内部或外部类),Modifier(修饰符),Package

newInstance//由构造器Constructer或Class对象调用返回相应类的对象

invoke(方法,方法的可变参数);// 由Method对象调用

setAccessable设置true以取消访问权限的检查

Field利用setXXX,getXXX方法反射读写值,如果是对象直接set,get


 反射生成JDK动态代理// by zjerry 不太明白

0 0
原创粉丝点击