【java基础之jdk源码】Object
最新在整体回归下java基础薄弱环节,以下为自己整理笔记,若有理解错误,请批评指正,谢谢。
java.lang.Object为java所有类的基类,所以一般的类都可用重写或直接使用Object下方法,以下为逻辑结构图,没有画类图
(注: 以上绿色方法为 非native方法 粉色方法为 native方法)
那么问题来了 :
1、what is a native object?
本人理解: native关键字标识的java方法为本地方法,底层是有c/c++编写的程序编译后dll文件,java加载dll文件后,
可用通过本地方法调用dll中函数,如有疑问可用参考JNI使用方式,看参考:http://blog.csdn.net/yangjiali014/article/details/1633017
以下为Object类对应openjdk\jdk\src\share\native\java\lang\Object.c的源码片段1:
- static JNINativeMethod methods[] = {
- {"hashCode", "()I", (void *)&JVM_IHashCode},
- {"wait", "(J)V", (void *)&JVM_MonitorWait},
- {"notify", "()V", (void *)&JVM_MonitorNotify},
- {"notifyAll", "()V", (void *)&JVM_MonitorNotifyAll},
- {"clone", "()Ljava/lang/Object;", (void *)&JVM_Clone},
- };
网友见解:http://stackoverflow.com/questions/4568972/what-is-a-native-object
2、Why exist native method in Object Class?
本人理解:涉及调用系统及考虑性能,使用c++或c实现更佳
网友见解:http://stackoverflow.com/questions/10578764/why-are-hashcode-and-getclass-native-methods
http://stackoverflow.com/questions/27224577/why-is-object-clone-native-in-java
现在按上图逐个方法讲讲理解:
1、Object():默认构造函数
2、 registerNatives(): 用于注册 代码片段1中的本地方法到jvm中
java代码 片段2
- private static native void registerNatives();
- static {
- registerNatives();
- }
对应c++代码 片段3
- JNIEXPORT void JNICALL
- Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls)
- {
- (*env)->RegisterNatives(env, cls,
- methods, sizeof(methods)/sizeof(methods[]));
- }
3、final getClass(): (不能重写方法)方法说明中已经提示:Returns:The Class
object that represents the runtime class of this object.
来个简单例子 片段4
- package jdk;
- public class ObjectTest {
- public static void main(String[] args) {
- A a = new B();
- System.out.println(a.getClass());
- }
- }
- class A {
- static{
- System.out.println("初始化a");
- }
- }
- class B extends A{
- static{
- System.out.println("初始化b");
- }
- }
输出结果:
可以看到getClass返回的为class B 非 A。
4、hashCode():返回一个整数的值依赖于内部表示堆上的对象的指针
方法说明:This is typically implemented by converting the internal address of the object into an integer, but this implementation technique is not required by the Java™ programming language
一起看下native方法 位于openjdk\hotspot\src\share\vm\prims\jvm.cpp中 JVM_IHashCode的实现
- JVM_ENTRY(jint, JVM_IHashCode(JNIEnv* env, jobject handle))
- JVMWrapper("JVM_IHashCode");
- // as implemented in the classic virtual machine; return 0 if object is NULL
- return handle == NULL ? : ObjectSynchronizer::FastHashCode (THREAD, JNIHandles::resolve_non_null(handle)) ;
- JVM_END
调用了ObjectSynchronizer::FastHashCode方法,位于openjdk\hotspot\src\share\vm\runtime\synchronizer.cpp中 第530行起
- static inline intptr_t get_next_hash(Thread * Self, oop obj) {
- intptr_t value = ;
- if (hashCode == ) {
- // This form uses an unguarded global Park-Miller RNG,
- // so it's possible for two threads to race and generate the same RNG.
- // On MP system we'll have lots of RW access to a global, so the
- // mechanism induces lots of coherency traffic.
- value = os::random() ;
- } else
- if (hashCode == ) {
- // This variation has the property of being stable (idempotent)
- // between STW operations. This can be useful in some of the 1-0
- // synchronization schemes.
- intptr_t addrBits = intptr_t(obj) >> ;
- value = addrBits ^ (addrBits >> ) ^ GVars.stwRandom ;
- } else
- if (hashCode == ) {
- value = ; // for sensitivity testing
- } else
- if (hashCode == ) {
- value = ++GVars.hcSequence ;
- } else
- if (hashCode == ) {
- value = intptr_t(obj) ;
- } else {
- // Marsaglia's xor-shift scheme with thread-specific state
- // This is probably the best overall implementation -- we'll
- // likely make this the default in future releases.
- unsigned t = Self->_hashStateX ;
- t ^= (t << ) ;
- Self->_hashStateX = Self->_hashStateY ;
- Self->_hashStateY = Self->_hashStateZ ;
- Self->_hashStateZ = Self->_hashStateW ;
- unsigned v = Self->_hashStateW ;
- v = (v ^ (v >> )) ^ (t ^ (t >> )) ;
- Self->_hashStateW = v ;
- value = v ;
- }
- value &= markOopDesc::hash_mask;
- if (value == ) value = 0xBAD ;
- assert (value != markOopDesc::no_hash, "invariant") ;
- TEVENT (hashCode: GENERATE) ;
- return value;
- }
- //
- intptr_t ObjectSynchronizer::FastHashCode (Thread * Self, oop obj) {
- if (UseBiasedLocking) {
- // NOTE: many places throughout the JVM do not expect a safepoint
- // to be taken here, in particular most operations on perm gen
- // objects. However, we only ever bias Java instances and all of
- // the call sites of identity_hash that might revoke biases have
- // been checked to make sure they can handle a safepoint. The
- // added check of the bias pattern is to avoid useless calls to
- // thread-local storage.
- if (obj->mark()->has_bias_pattern()) {
- // Box and unbox the raw reference just in case we cause a STW safepoint.
- Handle hobj (Self, obj) ;
- // Relaxing assertion for bug 6320749.
- assert (Universe::verify_in_progress() ||
- !SafepointSynchronize::is_at_safepoint(),
- "biases should not be seen by VM thread here");
- BiasedLocking::revoke_and_rebias(hobj, false, JavaThread::current());
- obj = hobj() ;
- assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
- }
- }
- // hashCode() is a heap mutator ...
- // Relaxing assertion for bug 6320749.
- assert (Universe::verify_in_progress() ||
- !SafepointSynchronize::is_at_safepoint(), "invariant") ;
- assert (Universe::verify_in_progress() ||
- Self->is_Java_thread() , "invariant") ;
- assert (Universe::verify_in_progress() ||
- ((JavaThread *)Self)->thread_state() != _thread_blocked, "invariant") ;
- ObjectMonitor* monitor = NULL;
- markOop temp, test;
- intptr_t hash;
- markOop mark = ReadStableMark (obj);
- // object should remain ineligible for biased locking
- assert (!mark->has_bias_pattern(), "invariant") ;
- if (mark->is_neutral()) {
- hash = mark->hash(); // this is a normal header
- if (hash) { // if it has hash, just return it
- return hash;
- }
- hash = get_next_hash(Self, obj); // allocate a new hash code
- temp = mark->copy_set_hash(hash); // merge the hash code into header
- // use (machine word version) atomic operation to install the hash
- test = (markOop) Atomic::cmpxchg_ptr(temp, obj->mark_addr(), mark);
- if (test == mark) {
- return hash;
- }
- // If atomic operation failed, we must inflate the header
- // into heavy weight monitor. We could add more code here
- // for fast path, but it does not worth the complexity.
- } else if (mark->has_monitor()) {
- monitor = mark->monitor();
- temp = monitor->header();
- assert (temp->is_neutral(), "invariant") ;
- hash = temp->hash();
- if (hash) {
- return hash;
- }
- // Skip to the following code to reduce code size
- } else if (Self->is_lock_owned((address)mark->locker())) {
- temp = mark->displaced_mark_helper(); // this is a lightweight monitor owned
- assert (temp->is_neutral(), "invariant") ;
- hash = temp->hash(); // by current thread, check if the displaced
- if (hash) { // header contains hash code
- return hash;
- }
- // WARNING:
- // The displaced header is strictly immutable.
- // It can NOT be changed in ANY cases. So we have
- // to inflate the header into heavyweight monitor
- // even the current thread owns the lock. The reason
- // is the BasicLock (stack slot) will be asynchronously
- // read by other threads during the inflate() function.
- // Any change to stack may not propagate to other threads
- // correctly.
- }
该方法一般会被子类重写,String方法的hashCode方法代码 片段5
计算方法是 s[0]31^(n-1) + s[1]31^(n-2) + … + s[n-1],其中s[0]表示字符串的第一个字符,n表示字符串长度;
- public int hashCode() {
- int h = hash;
- if (h == 0 && value.length > 0) {
- char val[] = value;
- for (int i = 0; i < value.length; i++) {
- h = 31 * h + val[i];
- }
- hash = h;
- }
- return h;
- }
5、equals():返回 2个对象的内存地址是否相等
源码 片段6
- public boolean equals(Object obj) {
- return (this == obj);
- }
该方法一般会被子类重写,String方法的equal方法代码 片段7
先比较String对象内存地址相同,若相同则返回true,否则判断String对象对应字符的内容是否相等,若相等则返回true
- public boolean equals(Object anObject) {
- if (this == anObject) {
- return true;
- }
- if (anObject instanceof String) {
- String anotherString = (String)anObject;
- int n = value.length;
- if (n == anotherString.value.length) {
- char v1[] = value;
- char v2[] = anotherString.value;
- int i = 0;
- while (n-- != 0) {
- if (v1[i] != v2[i])
- return false;
- i++;
- }
- return true;
- }
- }
- return false;
- }
6、clone() throws CloneNotSupportedException:返回复制对象
先看下方法的说明:Note that all arrays are considered to implement the interface Cloneable and that the return type of the clone method of an array type T[] is T[] where T is any reference or primitive type
一起看下native方法 位于openjdk\hotspot\src\share\vm\prims\jvm.cpp中 JVM_Clone的实现 片段8
- JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
- JVMWrapper("JVM_Clone");
- Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
- const KlassHandle klass (THREAD, obj->klass());
- JvmtiVMObjectAllocEventCollector oam;
- #ifdef ASSERT
- // Just checking that the cloneable flag is set correct
- if (obj->is_javaArray()) {
- guarantee(klass->is_cloneable(), "all arrays are cloneable");
- } else {
- guarantee(obj->is_instance(), "should be instanceOop");
- bool cloneable = klass->is_subtype_of(SystemDictionary::Cloneable_klass());
- guarantee(cloneable == klass->is_cloneable(), "incorrect cloneable flag");
- }
- #endif
- // Check if class of obj supports the Cloneable interface.
- // All arrays are considered to be cloneable (See JLS 20.1.5)
- if (!klass->is_cloneable()) {
- ResourceMark rm(THREAD);
- THROW_MSG_0(vmSymbols::java_lang_CloneNotSupportedException(), klass->external_name());
- }
- // Make shallow object copy
- const int size = obj->size();
- oop new_obj = NULL;
- if (obj->is_javaArray()) {
- const int length = ((arrayOop)obj())->length();
- new_obj = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL);
- } else {
- new_obj = CollectedHeap::obj_allocate(klass, size, CHECK_NULL);
- }
- // 4839641 (4840070): We must do an oop-atomic copy, because if another thread
- // is modifying a reference field in the clonee, a non-oop-atomic copy might
- // be suspended in the middle of copying the pointer and end up with parts
- // of two different pointers in the field. Subsequent dereferences will crash.
- // 4846409: an oop-copy of objects with long or double fields or arrays of same
- // won't copy the longs/doubles atomically in 32-bit vm's, so we copy jlongs instead
- // of oops. We know objects are aligned on a minimum of an jlong boundary.
- // The same is true of StubRoutines::object_copy and the various oop_copy
- // variants, and of the code generated by the inline_native_clone intrinsic.
- assert(MinObjAlignmentInBytes >= BytesPerLong, "objects misaligned");
- Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj,
- (size_t)align_object_size(size) / HeapWordsPerLong);
- // Clear the header
- new_obj->init_mark();
- // Store check (mark entire object and let gc sort it out)
- BarrierSet* bs = Universe::heap()->barrier_set();
- assert(bs->has_write_region_opt(), "Barrier set does not have write_region");
- bs->write_region(MemRegion((HeapWord*)new_obj, size));
- // Caution: this involves a java upcall, so the clone should be
- // "gc-robust" by this stage.
- if (klass->has_finalizer()) {
- assert(obj->is_instance(), "should be instanceOop");
- new_obj = instanceKlass::register_finalizer(instanceOop(new_obj), CHECK_NULL);
- }
- return JNIHandles::make_local(env, oop(new_obj));
- JVM_END
隐含意思:数组类型默认可以直接克隆,而其他对象实现clone需要先实现Cloneable接口,否则抛出CloneNotSupportedException异常
问题1:对象的创建有多中方式,类似 new 、getInstance、clone等 clone有什么好处?
问题2:对象调用clone方法生成的对象 和 原对象是否还有什么关联关系?
问题3 : 对象clone存在 “浅复制”、“深复制”概念,怎么区分?
带着这3个问题,理解Object clone方法:
1、一般native方法比java中非native方法执行效率高 ,看示例 片段9
- package jdk;
- import java.util.Calendar;
- import java.util.Date;
- public class ObjectCloneTest1 {
- static final int N = 100000;
- public static void main(String[] args) {
- final Date date = new Date();
- {
- final long startTime = System.currentTimeMillis();
- for (int i = 0; i < N; i++) {
- Date date2 = (Date) date.clone();
- }
- final long endTime = System.currentTimeMillis();
- System.out.println("clone:" + (endTime - startTime) + "ms");
- }
- {
- final long startTime = System.currentTimeMillis();
- for (int i = 0; i < N; i++) {
- final Calendar cal = Calendar.getInstance();
- cal.setTime(date);
- final Date date2 = cal.getTime();
- }
- final long endTime = System.currentTimeMillis();
- System.out.println("Calender.setTime:" + (endTime - startTime) + "ms");
- }
- }
- }
2、clone生成的新对象与原对象的关系,需要区别2个对象建是否存在相同的引用或对应的内存地址是否存在共用情况,若存在则 该次clone为 “浅复制”,否则为“深复制”, 而且Object的clone方法是属于 “浅复制”,看示例 片段10
- package jdk;
- public class ObjectCloneTest2 {
- public static void main(String[] args) {
- Animal a1 = new Animal(1, "pig");
- Animal a2 = (Animal) a1.clone();
- System.out.println(a1.getName() == a2.getName() ? "浅复制" : "深复制");
- System.out.println(a1);
- a1.setAge(11);
- a1.setName("big pig");
- System.out.println(a1.age + ":" + a1.name);
- System.out.println(a2);
- System.out.println(a2.age + ":" + a2.name);
- }
- }
- class Animal implements Cloneable{
- int age;
- String name;
- Animal(int age, String name) {
- this.age = age;
- this.name = name;
- }
- public Animal clone() {
- Animal o = null;
- try {
- o = (Animal) super.clone();
- } catch (CloneNotSupportedException e) {
- e.printStackTrace();
- }
- return o;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
"深复制"时,需要将共同关联的引用也复制完全看示例 片段11
- package jdk;
- public class ObjectCloneTest3 {
- public static void main(String[] args) {
- Person p1 = new Person(10, "ll", new Race("yellow", "Asia"));
- Person p2 = (Person) p1.clone();
- System.out.println(p1.getRace() == p2.getRace());
- System.out.println(p1.getTestArray() == p2.getTestArray());
- }
- }
- class Person implements Cloneable {
- int age;
- String name;
- Race race;
- int[] testArray = { 1, 23, 5, 6, 0 };
- Person(int age, String name, Race race) {
- this.age = age;
- this.name = name;
- this.race = race;
- }
- public Person clone() {
- Person o = null;
- try {
- o = (Person) super.clone();
- o.setRace(this.race.clone());
- o.setTestArray(testArray.clone());
- } catch (CloneNotSupportedException e) {
- e.printStackTrace();
- }
- return o;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Race getRace() {
- return race;
- }
- public void setRace(Race race) {
- this.race = race;
- }
- public void setTestArray(int[] testArray) {
- this.testArray = testArray;
- }
- public int[] getTestArray() {
- return testArray;
- }
- }
- class Race implements Cloneable {
- String color; // 颜色
- String distribution; // 分布
- public Race(String color, String distribution) {
- super();
- this.color = color;
- this.distribution = distribution;
- }
- public Race clone() throws CloneNotSupportedException {
- return (Race) super.clone();
- }
- }
7、toString():a string representation of the object.
方法说明:
The toString
method for class Object
returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@
', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:
- getClass().getName() + '@' + Integer.toHexString(hashCode())
默认返回对象的名称及引用地址,但一般被子类重写用于说明子类相关属性值描述
8、final notify() : 不能被重写,用于唤醒一个在因等待该对象(调用了wait方法)被处于等待状态(waiting 或 time_wait)的线程,该方法只能同步方法或同步块中调用
方法说明:Wakes up a single thread that is waiting on this object's monitor. If any threads are waiting on this object, one of them is chosen to be awakened. The choice is arbitrary and occurs at the discretion of the implementation. A thread waits on an object's monitor by calling one of the wait
methods.
9、final notifyAll():不能被重写,用于唤醒所有在因等待该对象(调用wait方法)被处于等待状态(waiting或time_waiting)的线程,该方法只能同步方法或同步块中调用
方法说明:Wakes up all threads that are waiting on this object's monitor. A thread waits on an object's monitor by calling one of the wait
methods.
10、final wait(long timeout):不能被重写,用于在线程调用中,导致当前线程进入等待状态(time_waiting),timeout单位为毫秒,该方法只能同步方法或同步块中调用,超过设置时间后线程重新进入可运行状态
方法说明:Note that the wait
method, as it places the current thread into the wait set for this object, unlocks only this object; any other objects on which the current thread may be synchronized remain locked while the thread waits.
11、final wait(long timeout, int nanos):不能被重写,在jdk1.8中看当,没有什么特殊作用类似 wait(long timeout)方法,片段12
- if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
- timeout++;
- }
12、final void wait()::不能被重写,用于在线程调用中,导致当前线程进入阻塞状态(waiting),该方法只能同步方法或同步块中调用,不会自动,片段13
方法说明:The specified amount of real time has elapsed, more or less. If timeout is zero, however, then real time is not taken into consideration and the thread simply waits until notified.
- public final void wait() throws InterruptedException {
- wait(0);
- }
8,9,10,11,12几个方法一般配套使用,先了解一下JAVA 线程执行模型
详细看示例 片段14
- synchronized (obj) {
- while (<condition does not hold>)
- obj.wait(timeout);
- ... // Perform action appropriate to condition
- }
- package jdk;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.ThreadFactory;
- import java.util.concurrent.atomic.AtomicInteger;
- public class ObjectWaitTest1 {
- static Object lock = new Object();
- public static void main(String[] args) {
- ExecutorService executeService = Executors.newCachedThreadPool(new MyThreadFactory());
- for (int i = 0; i < 10; i++) {
- executeService.submit(() -> {
- synchronized (lock) {
- try {
- System.out.println(Thread.currentThread().getName() + " begin");
- lock.wait(1000 * 30); // wiat 30s
- } catch (Exception e) {
- e.printStackTrace();
- }
- System.out.println(Thread.currentThread().getName() + " finish");
- }
- });
- }
- executeService.shutdown();
- }
- static class MyThreadFactory implements ThreadFactory {
- private final AtomicInteger threadNumber = new AtomicInteger(1);
- public Thread newThread(Runnable r) {
- return new Thread(r, "mythiread - " + threadNumber.getAndIncrement());
- }
- }
- }
执行wait过程中堆栈信息:
再来个生产消费者的示例 片段15
- package jdk;
- import java.util.LinkedList;
- import java.util.Queue;
- import java.util.Random;
- public class ObjectWaitTest2 {
- static Object lock = new Object();
- public static void main(String[] args) {
- int maxSize = 10;
- Queue<Integer> buffer = new LinkedList<>();
- Thread producer = new Producer(buffer, maxSize, "Producer");
- Thread comsuner = new Comsumer(buffer, maxSize, "comsuner");
- producer.start();
- comsuner.start();
- }
- }
- class Producer extends Thread {
- private Queue<Integer> queue;
- private int maxSize;
- public Producer(Queue<Integer> queue, int maxSize, String name) {
- super(name);
- this.maxSize = maxSize;
- this.queue = queue;
- }
- @Override
- public void run() {
- while (true) {
- synchronized (queue) {
- if (queue.size() == maxSize) {
- try {
- System.out.println("Queue is full, Producer wair for Comsumer to task something from queue");
- queue.wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- Random r = new Random();
- int value = r.nextInt();
- queue.add(value);
- System.out.println("Producer value : " + value);
- queue.notifyAll();
- }
- }
- }
- }
- class Comsumer extends Thread {
- private Queue<Integer> queue;
- private int maxSize;
- public Comsumer(Queue<Integer> queue, int maxSize, String name) {
- super(name);
- this.maxSize = maxSize;
- this.queue = queue;
- }
- @Override
- public void run() {
- while (true) {
- synchronized (queue) {
- if (queue.isEmpty()) {
- try {
- System.out.println("Queue is enpty, Comsumer wair for Producer to put something in queue");
- queue.wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- System.out.println("Comsumer value : " + queue.remove());
- queue.notifyAll();
- }
- }
- }
- }
13、finalize():Object的protected方法,子类可以覆盖该方法以实现资源清理工作,GC在回收对象之前调用该方法
方法说明:Called by the garbage collector on an object when garbage collection determines that there are no more references to the object. A subclass overrides the finalize
method to dispose of system resources or to perform other cleanup.
,该方法只能同步方法或同步块中调用
【java基础之jdk源码】Object的更多相关文章
- 【java基础之jdk源码】集合类
最近在整理JAVA 基础知识,从jdk源码入手,今天就jdk中 java.util包下集合类进行理解 先看图 从类图结构可以了解 java.util包下的2个大类: 1.Collecton:可以理解为 ...
- java基础集合类——ArrayList 源码略读
ArrayList是java的动态数组,底层是基于数组实现. 1. 成员变量 public class ArrayList<E> extends AbstractList<E> ...
- Java基础(八)--String(源码)、StringBuffer、StringBuilder
String源码:基于jdk1.8 public final class String implements Serializable, Comparable<String>, CharS ...
- jdk源码Object类解析
一 简介 java.lang.Object,是Java所有类的父类,在你编写一个类的时候,若无指定父类(没有显式extends一个父类),会默认的添加Object为该类的父类. 在JDK 6之前是编译 ...
- Java基础try-with-resource语法源码分析
众所周知,所有被打开的系统资源,比如流.文件或者Socket连接等,都需要被开发者手动关闭,否则随着程序的不断运行,资源泄露将会累积成重大的生产事故. 在Java的江湖中,存在着一种名为finally ...
- JDK源码学习笔记——Object
一.源码解析 public class Object { /** * 一个本地方法,具体是用C(C++)在DLL中实现的,然后通过JNI调用 */ private static native void ...
- 从JDK源码角度看Object
Java的Object是所有其他类的父类,从继承的层次来看它就是最顶层根,所以它也是唯一一个没有父类的类.它包含了对象常用的一些方法,比如getClass.hashCode.equals.clone. ...
- 一点一点看JDK源码(三)java.util.ArrayList 前偏
一点一点看JDK源码(三)java.util.ArrayList liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 1.综述 ArrayLi ...
- Java中集合框架,Collection接口、Set接口、List接口、Map接口,已经常用的它们的实现类,简单的JDK源码分析底层实现
(一)集合框架: Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(实现接口的类).所有抽象出来的数据结构和操作(算法)统称为集合框架. 程序员在具体应用的时候,不必考虑数据结构和 ...
随机推荐
- 大数据竞赛平台——Kaggle 入门
Reference: http://blog.csdn.net/witnessai1/article/details/52612012 Kaggle是一个数据分析的竞赛平台,网址:https://ww ...
- win8.1 64位+oracle11g R2 64位 +powerdesigner破解版 64位+PL/SQL
安装时搜索了很多帖子,很多就是复制粘贴(完全不需要什么IP,host),有的版本不对,有的版本太老,今天决定贴出自己的处女贴 oracle的安装很简单,不需要说什么了,PL/SQL真是恶心死 orac ...
- Reactive 网络状态 Activity indicator view
转动属性:Animating RAC(self.searchActivity, hidden) = [self.m_viewModel.m_searchCommand.executing not];
- post请求时2种传参方式
@Testpublic void dopost(){ String httpurl = "https://jin.caimao.com/api/user/loginSalt"; M ...
- Java中间件:淘宝网系统高性能利器(转)
淘宝网是亚太最大的网络零售商圈,其知名度毋庸置疑,吸引着越来越多的消费者从街头移步这里,成为其忠实粉丝.如此多的用户和交易量,也意味着海量的信息处理,其背后的IT架构的稳定性.可靠性也显得尤为重要.那 ...
- .net 设置版本号信息
1.AssemblyInfo.cs [assembly: AssemblyVersion("1.3.170116")] [assembly: AssemblyFileVersion ...
- javascript设计模式之解释器模式详解
http://www.jb51.net/article/50680.htm 神马是“解释器模式”? 先翻开<GOF>看看Definition:给定一个语言,定义它的文法的一种表示,并定义一 ...
- 纯代码实现CSS圆角
我这里说的是纯代码,是指的不使用图片实现圆角,图片实现圆角,这里就不说了. 纯代码实现圆角主要有3种方法: 第一种:CSS3圆角 #chaomao{ border-radius:2px 2 ...
- c#使用DotNetZip封装类操作zip文件(创建/读取/更新)实例
DotnetZip是一个开源类库,支持.NET的任何语言,可很方便的创建,读取,和更新zip文件.而且还可以使用在.NETCompact Framework中. 下载地址在这里:http://dot ...
- 基于Ubuntu 14.04构建mysql5.6 Docker镜像
我们的目的是创建一个基于Ubuntu 14.04 的MySQL的 Docker Image,并且在新创建出来的容器里自动启动MySQL服务接受外部连接 步骤: 1. 首先创建一个目录并在目录下创建一个 ...