不是。Java中的基本數據類型只有8個:byte、short、int、long、float、double、char、boolean;除了基本類型(primitive type)和枚舉類型(enumeration type),剩下的都是引用類型(reference type)。java
不正確。3.4是雙精度數,將雙精度型(double)賦值給浮點型(float)屬於下轉型(down-casting,也稱爲窄化)會形成精度損失,所以須要強制類型轉換float f =(float)3.4; 或者寫成float f =3.4F;。程序員
對於short s1 = 1; s1 = s1 + 1;因爲1是int類型,所以s1+1運算結果也是int 型,須要強制轉換類型才能賦值給short型。而short s1 = 1; s1 += 1;能夠正確編譯,由於s1+= 1;至關於s1 = (short)(s1 + 1);其中有隱含的強制類型轉換。編程
Java是一個近乎純潔的面向對象編程語言,可是爲了編程的方便仍是引入了基本數據類型,可是爲了可以將這些基本數據類型當成對象操做,Java爲每個基本數據類型都引入了對應的包裝類型(wrapper class),int的包裝類就是Integer,從Java 5開始引入了自動裝箱/拆箱機制,使得兩者能夠相互轉換。緩存
Java 爲每一個原始類型提供了包裝類型:安全
&運算符有兩種用法:(1)按位與;(2)邏輯與。&&運算符是短路與運算。邏輯與跟短路與的差異是很是巨大的,雖然兩者都要求運算符左右兩端的布爾值都是true整個表達式的值纔是true。&&之因此稱爲短路運算是由於,若是&&左邊的表達式的值是false,右邊的表達式會被直接短路掉,不會進行運算。不少時候咱們可能都須要用&&而不是&,例如在驗證用戶登陸時斷定用戶名不是null並且不是空字符串,應當寫爲:username != null &&!username.equals(「」),兩者的順序不能交換,更不能用&運算符,由於第一個條件若是不成立,根本不能進行字符串的equals比較,不然會產生NullPointerException異常。注意:邏輯或運算符(|)和短路或運算符(||)的差異也是如此。多線程
Math.round(11.5)的返回值是12,Math.round(-11.5)的返回值是-11。四捨五入的原理是在參數上加0.5而後進行下取整。併發
在Java 5之前,switch(expr)中,expr只能是byte、short、char、int。從Java 5開始,Java中引入了枚舉類型,expr也能夠是enum類型,從Java 7開始,expr還能夠是字符串(String),可是長整型(long),浮點數(float)在目前全部的版本中都是不能夠的。app
不對,若是兩個對象x和y知足x.equals(y) == true,它們的哈希碼(hash code)應當相同。框架
Java對於eqauls方法和hashCode方法是這樣規定的:編程語言
(1)若是兩個對象相同(equals方法返回true),那麼它們的hashCode值必定要相同;
(2)若是兩個對象的hashCode相同,它們並不必定相同。固然,你未必要按照要求去作,可是若是你違背了上述原則就會發如今使用容器時,相同的對象能夠出如今Set集合中,同時增長新元素的效率會大大降低(對於使用哈希存儲的系統,若是哈希碼頻繁的衝突將會形成存取性能急劇降低)。
補充:關於equals和hashCode方法,不少Java程序都知道,但不少人也就是僅僅知道而已,在Joshua Bloch的大做《Effective Java》(不少軟件公司,《Effective Java》、《Java編程思想》以及《重構:改善既有代碼質量》是Java程序員必看書籍,若是你還沒看過,那就趕忙去亞馬遜買一本吧)中是這樣介紹equals方法的:首先equals方法必須知足自反性(x.equals(x)必須返回true)、對稱性(x.equals(y)返回true時,y.equals(x)也必須返回true)、傳遞性(x.equals(y)和y.equals(z)都返回true時,x.equals(z)也必須返回true)和一致性(當x和y引用的對象信息沒有被修改時,屢次調用x.equals(y)應該獲得一樣的返回值),並且對於任何非null值的引用x,x.equals(null)必須返回false。
實現高質量的equals方法的訣竅包括:
是值傳遞。Java語言的方法調用只支持參數的值傳遞。當一個對象實例做爲一個參數被傳遞到方法中時,參數的值就是對該對象的引用。對象的屬性能夠在被調用過程當中被改變,但對對象引用的改變是不會影響到調用者的。C++和C#中能夠經過傳引用或傳輸出參數來改變傳入的參數的值。
Java平臺提供了兩種類型的字符串:String和StringBuffer/StringBuilder,它們能夠儲存和操做字符串。其中String是隻讀字符串,也就意味着String引用的字符串內容是不能被改變的。而StringBuffer/StringBuilder類表示的字符串對象能夠直接進行修改。StringBuilder是Java 5中引入的,它和StringBuffer的方法徹底相同,區別在於它是在單線程環境下使用的,由於它的全部方面都沒有被synchronized修飾,所以它的效率也比StringBuffer要高。
都不能。抽象方法須要子類重寫,而靜態的方法是沒法被重寫的,所以兩者是矛盾的。本地方法是由本地代碼(如C代碼)實現的方法,而抽象方法是沒有實現的,也是矛盾的。synchronized和方法的實現細節有關,抽象方法不涉及實現細節,所以也是相互矛盾的。
靜態變量是被static修飾符修飾的變量,也稱爲類變量,它屬於類,不屬於類的任何一個對象,一個類無論建立多少個對象,靜態變量在內存中有且僅有一個拷貝;實例變量必須依存於某一實例,須要先建立對象而後經過對象才能訪問到它。靜態變量能夠實現讓多個對象共享內存。
補充:在Java開發中,上下文類和工具類中一般會有大量的靜態成員。
不能夠,靜態方法只能訪問靜態成員,由於非靜態方法的調用要先建立對象,在調用靜態方法時可能對象並無被初始化。
淺拷貝:被複制對象的全部變量都含有與原來的對象相同的值,而全部的對其餘對象的引用仍然指向原來的對象。換言之,淺拷貝僅僅複製所考慮的對象,而不復制它所引用的對象。
深拷貝:被複制對象的全部變量都含有與原來的對象相同的值,而那些引用其餘對象的變量將指向被複制過的新對象,而再也不是原有的那些被引用的對象。換言之,深拷貝把要複製的對象所引用的對象都複製了一遍。
有兩種方式:
代碼以下:
import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class MyUtil { private MyUtil() { throw new AssertionError(); } public static <T> T clone(T obj) throws Exception { ByteArrayOutputStream bout = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bout); oos.writeObject(obj); ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bin); return (T) ois.readObject(); // 說明:調用ByteArrayInputStream或ByteArrayOutputStream對象的close方法沒有任何意義 // 這兩個基於內存的流只要垃圾回收器清理對象就可以釋放資源,這一點不一樣於對外部資源(如文件流)的釋放 } }
下面是測試代碼:
import java.io.Serializable; /** * 人類 * @author 駱昊 * */ class Person implements Serializable { private static final long serialVersionUID = -9102017020286042305L; private String name; // 姓名 private int age; // 年齡 private Car car; // 座駕 public Person(String name, int age, Car car) { this.name = name; this.age = age; this.car = car; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Car getCar() { return car; } public void setCar(Car car) { this.car = car; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", car=" + car + "]"; } } /** * 小汽車類 * @author 駱昊 * */ class Car implements Serializable { private static final long serialVersionUID = -5713945027627603702L; private String brand; // 品牌 private int maxSpeed; // 最高時速 public Car(String brand, int maxSpeed) { this.brand = brand; this.maxSpeed = maxSpeed; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public int getMaxSpeed() { return maxSpeed; } public void setMaxSpeed(int maxSpeed) { this.maxSpeed = maxSpeed; } @Override public String toString() { return "Car [brand=" + brand + ", maxSpeed=" + maxSpeed + "]"; } } class CloneTest { public static void main(String[] args) { try { Person p1 = new Person("Hao LUO", 33, new Car("Benz", 300)); Person p2 = MyUtil.clone(p1); // 深度克隆 p2.getCar().setBrand("BYD"); // 修改克隆的Person對象p2關聯的汽車對象的品牌屬性 // 原來的Person對象p1關聯的汽車不會受到任何影響 // 由於在克隆Person對象時其關聯的汽車對象也被克隆了 System.out.println(p1); } catch (Exception e) { e.printStackTrace(); } } }
注意:基於序列化和反序列化實現的克隆不只僅是深度克隆,更重要的是經過泛型限定,能夠檢查出要克隆的對象是否支持序列化,這項檢查是編譯器完成的,不是在運行時拋出異常,這種是方案明顯優於使用Object類的clone方法克隆對象。讓問題在編譯的時候暴露出來老是優於把問題留到運行時。
兩個對象,一個是靜態區的」xyz」,一個是用new建立在堆上的對象。
==是運算符,用於比較兩個變量是否相等,而equals是Object類的方法,用於比較兩個對象是否相等.默認Object類的equals方法是比較兩個對象的地址,此時和==的結果同樣.換句話說:基本類型比較用==,比較的是他們的值.默認下,對象用==比較時,比較的是內存地址,若是須要比較對象內容,須要重寫equal方法
若是a 和b 都是對象,則 a==b 是比較兩個對象的引用,只有當 a 和 b 指向的是堆中的同一個對象纔會返回 true,而 a.equals(b) 是進行邏輯比較,因此一般須要重寫該方法來提供邏輯一致性的比較。例如,String 類重寫 equals() 方法,因此能夠用於兩個不一樣對象,可是包含的字母相同的比較。
接口能夠繼承接口,並且支持多重繼承。抽象類能夠實現(implements)接口,抽象類可繼承具體類也能夠繼承抽象類。
(1)修飾類:表示該類不能被繼承;
(2)修飾方法:表示方法不能被重寫;
(3)修飾變量:表示變量只能一次賦值之後值不能被修改(常量)。
throw用於主動拋出java.lang.Throwable 類的一個實例化對象,意思是說你能夠經過關鍵字 throw 拋出一個 Error 或者 一個Exception,如:throw new IllegalArgumentException(「size must be multiple of 2″)。
throws 的做用是做爲方法聲明和簽名的一部分,方法被拋出相應的異常以便調用者能處理。Java 中,任何未處理的受檢查異常強制在 throws 子句中聲明。
Error表示系統級的錯誤和程序沒必要處理的異常,是恢復不是不可能但很困難的狀況下的一種嚴重問題;好比內存溢出,不可能期望程序能處理這樣的狀況;
Exception表示須要捕捉或者須要程序進行處理的異常,是一種設計或實現問題;也就是說,它表示若是程序運行正常,從不會發生的狀況。
Java經過面向對象的方法進行異常處理,把各類不一樣的異常進行分類,並提供了良好的接口。在Java中,每一個異常都是一個對象,它是Throwable類或其子類的實例。當一個方法出現異常後便拋出一個異常對象,該對象中包含有異常信息,調用這個對象的方法能夠捕獲到這個異常並能夠對其進行處理。
Java的異常處理是經過5個關鍵詞來實現的:try、catch、throw、throws和finally。
通常狀況下是用try來執行一段程序,若是系統會拋出(throw)一個異常對象,能夠經過它的類型來捕獲(catch)它,或經過老是執行代碼塊(finally)來處理; try用來指定一塊預防全部異常的程序; catch子句緊跟在try塊後面,用來指定你想要捕獲的異常的類型; throw語句用來明確地拋出一個異常; throws用來聲明一個方法可能拋出的各類異常(固然聲明異常時容許無病呻吟); finally爲確保一段代碼無論發生什麼異常情況都要被執行;
try語句能夠嵌套,每當遇到一個try語句,異常的結構就會被放入異常棧中,直到全部的try語句都完成。若是下一級的try語句沒有對某種異常進行處理,異常棧就會執行出棧操做,直到遇到有處理這種異常的try語句或者最終將異常拋給JVM。
異常表示程序運行過程當中可能出現的非正常狀態,運行時異常表示虛擬機的一般操做中可能遇到的異常,是一種常見運行錯誤,只要程序設計得沒有問題一般就不會發生。受檢異常跟程序運行的上下文環境有關,即便程序設計無誤,仍然可能因使用的問題而引起。Java編譯器要求方法必須聲明拋出可能發生的受檢異常,可是並不要求必須聲明拋出未被捕獲的運行時異常。
異常和繼承同樣,是面向對象程序設計中常常被濫用的東西,在Effective Java中對異常的使用給出瞭如下指導原則:
強引用,軟引用,弱引用,虛引用.不一樣的引用類型主要體如今GC上:
強引用:若是一個對象具備強引用,它就不會被垃圾回收器回收。即便當前內存空間不足,JVM也不會回收它,而是拋出 OutOfMemoryError 錯誤,使程序異常終止。若是想中斷強引用和某個對象之間的關聯,能夠顯式地將引用賦值爲null,這樣一來的話,JVM在合適的時間就會回收該對象
軟引用:在使用軟引用時,若是內存的空間足夠,軟引用就能繼續被使用,而不會被垃圾回收器回收,只有在內存不足時,軟引用纔會被垃圾回收器回收。
弱引用:具備弱引用的對象擁有的生命週期更短暫。由於當 JVM 進行垃圾回收,一旦發現弱引用對象,不管當前內存空間是否充足,都會將弱引用回收。不過因爲垃圾回收器是一個優先級較低的線程,因此並不必定能迅速發現弱引用對象
虛引用:顧名思義,就是形同虛設,若是一個對象僅持有虛引用,那麼它至關於沒有引用,在任什麼時候候均可能被垃圾回收器回收。
更多瞭解參見深刻對象引用: http://blog.csdn.net/dd864140130/article/details/49885811
不像C語言,咱們能夠控制內存的申請和釋放,在Java中有時候咱們須要適當的控制對象被回收的時機,所以就誕生了不一樣的引用類型,能夠說不一樣的引用類型實則是對GC回收時機不可控的妥協.有如下幾個使用場景能夠充分的說明:
利用軟引用和弱引用解決OOM問題:用一個HashMap來保存圖片的路徑和相應圖片對象關聯的軟引用之間的映射關係,在內存不足時,JVM會自動回收這些緩存圖片對象所佔用的空間,從而有效地避免了OOM的問題.
經過軟引用實現Java對象的高速緩存:好比咱們建立了一Person的類,若是每次須要查詢一我的的信息,哪怕是幾秒中以前剛剛查詢過的,都要從新構建一個實例,這將引發大量Person對象的消耗,而且因爲這些對象的生命週期相對較短,會引發屢次GC影響性能。此時,經過軟引用和 HashMap 的結合能夠構建高速緩存,提供性能.
內部類能夠有多個實例,每一個實例都有本身的狀態信息,而且與其餘外圍對象的信息相互獨立.在單個外圍類當中,可讓多個內部類以不一樣的方式實現同一接口,或者繼承同一個類.建立內部類對象的時刻不依賴於外部類對象的建立.內部類並無使人疑惑的」is-a」關係,它就像是一個獨立的實體.
內部類提供了更好的封裝,除了該外圍類,其餘類都不能訪問
很是不幸,DateFormat 的全部實現,包括 SimpleDateFormat 都不是線程安全的,所以你不該該在多線程序中使用,除非是在對外線程安全的環境中使用,如 將 SimpleDateFormat 限制在 ThreadLocal 中。若是你不這麼作,在解析或者格式化日期的時候,可能會獲取到一個不正確的結果。所以,從日期、時間處理的全部實踐來講,我強力推薦 joda-time 庫。
Java 中,可使用 SimpleDateFormat 類或者 joda-time 庫來格式日期。DateFormat 類容許你使用多種流行的格式來格式化日期。參見答案中的示例代碼,代碼中演示了將日期格式化成不一樣的格式,如 dd-MM-yyyy 或 ddMMyyyy。
下面有幾條能夠遵循的方法重載的最佳實踐來避免形成自動裝箱的混亂。
反射機制是Java語言中一個很是重要的特性,它容許程序在運行時進行自我檢查,同時也容許對其內部成員進行操做。
反射機制提供的功能主要有:獲得一個對象所屬的類;獲取一個類的全部成員變量和方法;在運行時建立對象;在運行時調用對象的方法;
登錄、權限攔截、日誌處理,以及各類 Java 框架,如 Spring,Hibernate,JUnit 提到註解就不能不說反射,Java 自定義註解是經過運行時靠反射獲取註解。
實際開發中,例如咱們要獲取某個方法的調用日誌,能夠經過 AOP(動態代理機制)給方法添加切面,經過反射來獲取方法包含的註解,若是包含日誌註解,就進行日誌記錄。 反射的實如今 Java 應用層面上講,是經過對 Class 對象的操做實現的,Class 對象爲咱們提供了一系列方法對類進行操做。在 JVM 這個角度來講,Class 文件是一組以 8 位字節爲基礎單位的二進制流,各個數據項目按嚴格的順序緊湊的排列在 Class 文件中,裏面包含了類、方法、字段等等相關數據。
本人免費整理了Java高級資料,涵蓋了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo高併發分佈式等教程,一共30G,須要本身領取。
傳送門:https://mp.weixin.qq.com/s/JzddfH-7yNudmkjT0IRL8Q