小馬最近在執行一個spring項目源碼翻譯為PHP的任務。所以復盤了下JAVA知識,做下筆記并分享。筆記目前還比較亂但基本涵蓋了主要知識點,入門起飛。
JAVA基礎語法
JAVA參考教程文檔(這里)。
是解釋型的語言(.java文件? javac->.class文件? 解釋器->JVM虛擬機),GO是編譯型的,PHP是解釋型的。
JAVA變量有枚舉類型,PHP8? 才開始支持枚舉類型。
重載(形參必須不同,方法名稱可以一樣)與重寫(可不變,內部核心變) --- 多態性。多態存在的三個必要條件:繼承,重寫,父類引用指向子類對象:Parent p = new Child();
PHP是沒有重載的,不能有同名函數。
多態的優點:
1. 消除類型之間的耦合關系
2. 可替換性
3. 可擴充性
4. 接口性
5. 靈活性
6. 簡化性
當使用多態方式調用方法時,首先檢查父類中是否有該方法,如果沒有,則編譯錯誤;如果有,再去調用子類的同名方法。
多態的好處:可以使程序有良好的擴展,并可以對所有類的對象進行通用處理。
JAVA的字符串是 類對象,這和PHP和GO是不一樣的,PHP 字符串可以直接加號拼接,JAVA可以借助對象內函數來處理字符串拼接等操作(也可以直接加號拼)。
小馬理解,JAVA的package名有點類似? GO的包,PHP的命名空間。
JAVA數據結構
Java 集合框架(https://m.runoob.com/java/java-collections.html)
集合框架是一個用來代表和操縱集合的統一架構。所有的集合框架都包含如下內容:
接口:是代表集合的抽象數據類型。例如 Collection、List、Set、Map 等。之所以定義多個接口,是為了以不同的方式操作集合對象
實現(類):是集合接口的具體實現。從本質上講,它們是可重復使用的數據結構,例如:ArrayList、LinkedList、HashSet、HashMap。
算法:是實現集合接口的對象里的方法執行的一些有用的計算,例如:搜索和排序。這些算法被稱為多態,那是因為相同的方法可以在相似的接口上有著不同的實現。
集合框架體系如圖所示(找一下圖好理解)。
Java Iterator(迭代器)不是一個集合,它是一種用于訪問集合的方法,可用于迭代 ArrayList 和 HashSet 等集合。
// 創建集合
? ? ? ? ArrayList<String> sites = new ArrayList<String>();
? ? ? ? sites.add("Google");
? ? ? ? sites.add("Runoob");
? ? ? ? sites.add("Taobao");
? ? ? ? sites.add("Zhihu");
? ? ? ? // 獲取迭代器
? ? ? ? Iterator<String> it = sites.iterator();
? ? ? ? // 輸出集合中的第一個元素
? ? ? ? System.out.println(it.next());
Java Object 類是所有類的父類,也就是說 Java 的所有類都繼承了 Object,子類可以使用 Object 的所有方法。
泛型,泛型類(泛型類的聲明和非泛型類的聲明類似,除了在類名后面添加了類型參數聲明部分)。
?--- 這里與UML的泛化 是兩種概念,泛化有繼承的意思。
泛型類例子:
public class Box<T> {
? private T t;
? public void add(T t) {
? ? this.t = t;
? }
? public T get() {
? ? return t;
? }
? public static void main(String[] args) {
? ? Box<Integer> integerBox = new Box<Integer>();
? ? Box<String> stringBox = new Box<String>();
? ? integerBox.add(new Integer(10));
? ? stringBox.add(new String("菜鳥教程"));
? ? System.out.printf("整型值為 :%d\n\n", integerBox.get());
? ? System.out.printf("字符串為 :%s\n", stringBox.get());
? }
}
GO和PHP的泛型話題:Golang團隊認為在類型系統和運行時的復雜性花費太大,還沒找到可以和這個復雜性相抵的良好設計。內置的map和slice其實都有泛型的味道,加上可以用interface{}來構造容器,可以達到泛型的效果。所以目前為止還沒有直接的支持泛型。至于PHP,目前還沒必要支持泛型。
JAVA類型通配符
1、類型通配符一般是使用 ? 代替具體的類型參數。例如 List<?> 在邏輯上是 List<String>,List<Integer> 等所有 List<具體類型實參> 的父類。
2、類型通配符上限通過形如List來定義,如此定義就是通配符泛型值接受Number及其下層子類類型。
3、類型通配符下限通過形如 List<? super Number> 來定義,表示類型只能接受 Number 及其上層父類類型,如 Object 類型的實例。
對象的序列化和反序列化
類 ObjectInputStream 和 ObjectOutputStream 是高層次的數據流,它們包含反序列化和序列化對象的方法。
請注意,一個類的對象要想序列化成功,必須滿足兩個條件:該類必須實現 java.io.Serializable 接口。該類的所有屬性必須是可序列化的。如果有一個屬性不是可序列化的,則該屬性必須注明是短暫的。如果你想知道一個 Java 標準類是否是可序列化的,請查看該類的文檔。檢驗一個類的實例是否能序列化十分簡單, 只需要查看該類有沒有實現 java.io.Serializable接口。
Java 網絡編程
java.net 包中提供了兩種常見的網絡協議的支持:TCP? UDP
Socket 編程
套接字使用TCP提供了兩臺計算機之間的通信機制。 客戶端程序創建一個套接字,并嘗試連接服務器的套接字。
當連接建立時,服務器會創建一個 Socket 對象??蛻舳撕头掌鳜F在可以通過對 Socket 對象的寫入和讀取來進行通信。
java.net.Socket 類代表一個套接字,并且 java.net.ServerSocket 類為服務器程序提供了一種來監聽客戶端,并與他們建立連接的機制。
socket是一般的app用的(服務端之間的通信?),客戶端是任何的socket client, websocket 是web上用,客戶端一般是瀏覽器上的js或其他web客戶端 SDK? ?
Applet 是一種 Java 程序。它一般運行在支持 Java 的 Web 瀏覽器內。因為它有完整的 Java API 支持,所以 Applet 是一個全功能的 Java 應用程序。
<applet> 標簽是在HTML文件中嵌入 Applet 的基礎。
<applet code="HelloWorldApplet.class" width="320" height="120">
好多java實例demo(這里)。
Java 8 新特性
Java 8 (又稱為 jdk 1.8) 是 Java 語言開發的一個主要版本。 Oracle 公司于 2014 年 3 月 18 日發布 Java 8 ,它支持函數式編程,新的 JavaScript 引擎,新的日期 API,新的Stream API 等。
Java 9 新特性
注解的理解
JAVA注解是 jdk 5新特性,注解(也被稱為元數據)為我們在代碼中添加信息提供了一種形式化的方式。擁有如下優勢:簡單易讀的代碼,編譯器類型檢查,使用 annotation API 為自己的注解構造處理工具。即使 Java 定義了一些類型的元數據,但是一般來說注解類型的添加和如何使用完全取決于你。
注解基本語法
注解的語法十分簡單,主要是在現有語法中添加 @ 符號。比如常用的:
@Override:檢查該方法是否是重寫方法。如果發現其父類,或者是引用的接口中并沒有該方法時,會報編譯錯誤。
@Deprecated:標記過時方法。如果使用該方法,會報編譯警告。
@SuppressWarnings:每當創建涉及重復工作的類或接口時,你通??梢允褂米⒔鈦碜詣踊秃喕鞒獭?/p>
在這個例子中,注解可以和任何修飾符共同用于方法,諸如 public、static 或 void。從語法的角度上看,注解的使用方式和修飾符的使用方式一致。
自定義注解:
注意啊,interface前邊有個@,@interface?這是自定義注解,不是接口。
public @interface Student{
String name();? ? //屬性沒有默認值,使用時必須指定值。
int age() default 0 ;? //有默認值,使用時,可以不給,也可以給。
String[] hobbies();? //數組格式,按照數組格式賦值,只有一個時,可以省略大括號。
}
//這樣使用。
@Student(name="小老犇",hobbies={"放牛","吃草"})
public void abc(){
sout("注解使用");
}
注解中屬性的數據類型一共有三種:
八種基本數據類型(byte short int long float double boolean char)
Class, String, 枚舉, 注解
以上所有類型的類型數組。
元注解
【用于定義注解】的注解,通常用于注解的定義上:
@Target:目標,描述自定義注解的使用范圍,比如:類、接口、枚舉、方法等等。? ---- 自定義一個注解類型(有字典列表),然后用來約束檢查被 自定義注解注解的 元素:
我們定義了一個適用于類的注解,代碼如下所示:
@Target({ElementType.TYPE})
public @interface AnnotationTest {//注意啊,interface前邊有個@,這是自定義注解,不是接口。
}
@AnnotationTest
public class Test {
? ? //@AnnotationTest? Erro:'@AnnotationTest' not applicable to method
? ? public void method(){
? ? }
}
@Retention:保留,表示注解信息保存的時長。
值 說明
SOURCE 注解將被編譯器丟棄(該類型的注解信息只會保留在源碼里,源碼經過編譯后,注解信息會被丟棄,不會保留在編譯好的class文件里)
CLASS 注解在class文件中可用,但會被VM丟棄(該類型的注解信息會保留在源碼里和class文件里,在執行的時候,不會加載到虛擬機中),請注意,當注解未定義Retention值時,默認值是CLASS,如Java內置注解,@Override、@Deprecated、@SuppressWarnning等
RUNTIME VM 將在運行期也保留注解,因此可以通過反射機制讀取注解的信息。
@Documented:生成的JavaDoc文檔。
@Inherited:允許子類繼承父類的注解,一般情況下獲取不到父類注解。
@Repeatable:允許一個注解可以被使用一次或者多次(Java 8)。
不包含任何元素的注解稱為標記注解(marker annotation),例如上例中的 @AnnotationTest 就是標記注解。
注解元素
注解元素可用的類型如下所示:
所有基本類型(int、float、boolean等)
String
Class
enum
Annotation
以上類型的數組
不允許使用任何包裝類型,但是由于自動裝箱的存在,這不算是什么限制。注解也可以作為元素的類型。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
@Documented
public @interface AnnotationTest {
? ? int id();
? ? String value() default "value";
? ? double[] number();
}
public class Test {
? ? @AnnotationTest(id=1,value = "123",number = {1,2,3})
? ? public void method(){
? ? }
? ? @AnnotationTest(id=1,number = {1,2,3})
? ? public void method2(){
? ? }
}
編譯器會進行類型檢查,如果在注解某個方法時沒有給出指定值時,會編譯錯誤;使用default 關鍵字,則該注解的處理器會使用此元素的默認值。
使用反射操作注解
方法 說明
getAnnotations() 獲取元素上所有的注解
getDeclaredAnnotations() 獲取元素上所有的注解,不包括從父類(inherited)繼承
getAnnotation() 獲取元素上指定注解
getDeclaredAnnotation() 獲取元素上指定注解,不包括從父類(inherited)繼承
isAnnotationPresent() 指定類型的注解存在于此元素上,則返回 true,否則返回 false。
注解不支持繼承
Spring
筆者要提醒的是,千萬不要把Spring和Spring Framework搞混淆了,很多文章都錯誤的定義了spring:spring是一個一站式的輕量級的java開發框架,核心是控制反轉(IoC)和面向切面(AOP),針對于開發的WEB層(springMVC)、業務層(IoC)、持久層(jdbcTemplate)等都提供了多種配置解決方案。這是Spring Framework的定義,至于Spring,是整個生態。
Spring framework
即Spring,是其他Spring全家桶的基礎和核心:包括SpringMVC(業務開發)、SpringBoot(在MVC基礎上簡化了XML配置,自動裝配)、SpringCloud(一整套基于Spring Boot的微服務解決方案)、SpringData、SpringSecurity。
Spring由Rod Johnson創立,2004年發布了Spring框架的第一版,其目的是用戶簡化企業級開發的難度和周期。
所以,我們學習的時候不要避重就輕,應該以Spring Framework和Spring Boot為主,而不是Spring Cloud。
spring文檔:https://www.w3cschool.cn/wkspring/dcu91icn.html
spring視頻教程:https://www.imooc.com/video/3662
IOC
接口A a = new 接口A實現類A1()
a.echoA1name();
接口cache
cache? = new redis()
XML或注解方式? (實現IOC? bean對象容器)
一個beanid? 一個對象
xml? <bean id=''? 配置對應具體的類class="接口實現類"></bean>
.java 載入xml文件,然后? 某接口A? a =super.getBean('bean_id')
a.hello();//接口函數(得到接口實現類中的具體實現)
初始化bean容器
spring注入(bean對象互相注入):設值注入,構造注入? (配置xml文件bean完成實現)(https://www.imooc.com/video/3668)。? ----- 寫完代碼后(含注入代碼),然后依賴還需要通過 配置XML? bean來實現注入后的最終對象
bean配置項
bean作用域:? 單例,每次請求新建,每個http請求有效(像session),session(每個session內有效),global session
Spring 基于注解的配置
序號 注解 & 描述
1 @Required
@Required 注解應用于 bean 屬性的 setter 方法。? -----必須要在xml配置文件定義屬性
2 @Autowired
@Autowired 注解可以應用到 bean 屬性的 setter 方法,非 setter 方法,構造函數和屬性。---- 自動裝載(自定實例化 注入對象,不用在xml配置注入)
3 @Qualifier
通過指定確切的將被連線的 bean,@Autowired 和 @Qualifier 注解可以用來刪除混亂。
4 JSR-250 Annotations
Spring 支持 JSR-250 的基礎的注解,其中包括了 @Resource,@PostConstruct 和 @PreDestroy 注解。
AOP:面向切面編程? (適用于功能是垂直的)。實現方式:預編譯? aspectJ? 和 運行期動態代理spring-aop 。(https://www.w3cschool.cn/wkspring/izae1h9w.html)(http://www.lxweimin.com/p/38e2ba053ed7)
日志,事務,安全控制
thinkphp AOP(面向切面編程)鉤子和行為
在軟件業,AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。AOP是OOP的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生范型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。
AOP大概意思指:在程序需要擴展時,不該動原本的代碼
在thinkphp中實現類似java的AOP可以使用“行為”。
首先需要知道“切面”,在thinkphp 中稱為標簽位(鉤子,行為)。即在代碼的某個位子加入一個標簽,這個標簽代表執行一個或多個操作,thinkphp也提供了幾個標簽.
參:? https://www.kancloud.cn/manual/thinkphp5_1/354129
參:? https://www.kancloud.cn/manual/thinkphp5/118130
springBoot
spring的bean容器相關的注解有:@Required, @Autowired, @PostConstruct, @PreDestory。還有Spring3.0開始支持的JSR-330標準javax.inject.*中的注解(@Inject, @Named, @Qualifier, @Provider, @Scope, @Singleton).
springmvc相關的注解有:@Controller,@RequestMapping,@RequestParam, @ResponseBody等等。
@PostMapping("login")
@PostMapping
用于將POST請求映射到控制器處理方法上。具體來說,@PostMapping是一個作為快捷方式的組合注解等價于@RequestMapping(method = RequestMethod.POST)。
@Log("登錄")? ? 每個方法前面加注解,通過注解類實現攔截器。(Log類被定義為注解public @interface Log ,在具體某業務函數上加上注解代表該函數需要執行注解的攔截@Log("登錄") ,Log類(其實是一個攔截器實現)實現攔截器接口class Log implements HandlerInterceptor這樣即可實現在任意函數前加注解就可以日志寫入)?