簡單的說,批處理的做用就是自動的連續執行多條命令 .編寫bat處理文件可使用記事本的方式:java
常見批處理文件的命令:spring
echo 表示顯示此命令後的字符 編程
tiltle 設置窗口的標題。設計模式
echo off 表示在此語句後全部運行的命令都不顯示命令行自己 數組
color 設置窗體的字體顏色。緩存
@與echo off相象,但它是加在每一個命令行的最前面,表示運行時不顯示這一行的命令行(只能影響當前行)。 安全
pause 運行此句會暫停批處理的執行並在屏幕上顯示Press any key to continue...的提示,等待用戶按任意鍵後繼續 框架
rem 表示此命令後的字符爲解釋行(註釋),不執行,只是給本身從此參考用的(至關於程序中的註釋) 或者%註釋的內容%dom
%[1-9]表示參數,參數是指在運行批處理文件時在文件名後加的以空格(或者Tab)分隔的字符串ide
淺複製(淺克隆)被複制對象的全部變量都含有與原來對象相同的值,而全部的對其餘對象的引用仍然只指向原來的對象,換言之,淺複製僅僅複製鎖考慮的對象,而不復制它所引用的對象。
public class Student implements Cloneable{ String name; int age; Student(String name,int age){ this.name=name; this.age=age; }
public Object clone(){ Object o =null; try{ o=super.clone();//Object中的clone()識別出你要複製的哪個對象 } catch(CloneNotSupportedException e){ System.out.println(e.toString()); } return o; }
public static void main(String[] args){ Student s1 = new Student("zhang",18); Student s2 = (Student)s1.clone(); s2.name="li"; s2.age=20; System.out.println("name="+s1.name+","+"age="+s1.age);//修改學生2後不影響學生1的值 } } |
深複製(深克隆)被複制對象的全部變量都含有與原來的對象相同的值,除去那些引用其餘對象的變量,那些引用其餘對象的變量將指向被複制過的新對象,而再也不試原有的那些被引用的對象,換言之,深複製把要複製的對象所引用的對象都複製了一遍。
把對象寫到流裏的過程是串行化(Serilization)過程,可是在Java程序師圈子裏又很是形象地稱爲「冷凍」或者「醃鹹菜(picking)」過程;而把對象從流中讀出來的並行化(Deserialization)過程則叫作「解凍」或者「回鮮(depicking)」過程。應當指出的是,寫在流裏的是對象的一個拷貝,而原對象仍然存在於JVM裏面,所以「醃成鹹菜」的只是對象的一個拷貝,Java鹹菜還能夠回鮮。
在Java語言裏深複製一個對象,經常能夠先使對象實現Serializable接口,而後把對象(實際上只是對象的一個拷貝)寫到一個流裏(醃成鹹菜),再從流裏讀出來(把鹹菜回鮮),即可以重建對象。
public Object deepClone() { //將對象寫到流裏 ByteArrayOutoutStream bo=new ByteArrayOutputStream(); ObjectOutputStream oo=new ObjectOutputStream(bo); oo.writeObject(this); //從流裏讀出來 ByteArrayInputStream bi=new ByteArrayInputStream(bo.toByteArray()); ObjectInputStream oi=new ObjectInputStream(bi); return(oi.readObject()); } |
因爲Java具有自動的垃圾回收機制,當咱們使用完對象以後,它們會被自動回收,是否是咱們在Java程序中不須要再考慮內存管理了嗎?
請看以下程序:
class Stack { private Object[] elements; // 初始化角標 int index = 0; // 默認初始化容量 private int initialCapacity = 10;
public Stack() { elements = new Object[initialCapacity]; }
// 壓棧 push public void push(Object e) { ensureCapacity(); elements[index++] = e; // System.out.println(index); }
// 彈棧 pop public Object pop() { if (index == 0) { throw new RuntimeException("沒有元素"); } return elements[--index]; }
private void ensureCapacity() { if (index == elements.length) { elements = Arrays.copyOf(elements, index * 2 + 1); } } }
|
注意:從棧中彈出的對象不會做爲垃圾回收,即便程序再也不使用這些對象,由於棧內部繼續維護着這些對象.最終可能會致使內存佔用的不斷增長,程序性能下降.這就是內存泄漏.
改進版本
class Stack { private Object[] elements; // 初始化角標 int index = 0; // 默認初始化容量 private int initialCapacity = 10;
public Stack() { elements = new Object[initialCapacity]; }
// 壓棧 push public void push(Object e) { ensureCapacity(); elements[index++] = e; // System.out.println(index); }
// 彈棧 pop public Object pop() { if (index == 0) { throw new RuntimeException("沒有元素"); } Object obj = elements[--index]; elements[index] = null; return obj; }
private void ensureCapacity() { if (index == elements.length) { elements = Arrays.copyOf(elements, index * 2 + 1); } } } |
設計模式(Design pattern)是一套被反覆使用、多數人知曉的、通過分類編目的、代碼設計經驗的總結。使用設計模式是爲了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。
有時又被稱爲
發佈-訂閱<Publish/Subscribe>模式、
模型-視圖<Model/View>模式、
源-收聽者<Source/Listener>模式
或從屬者<Dependents>模式)
這是軟件設計模式的一種。
觀察者模式(Observer)完美的將觀察者和被觀察的對象分離開。
此種模式中,一個目標物件管理全部相依於它的觀察者物件,而且在它自己的狀態改變時主動發出通知。
這一般透過呼叫各觀察者所提供的方法來實現。
此種模式一般被用來實做事件處理系統。
有多個觀察者時,不能夠依賴特定的通知次序。
Swing大量使用觀察者模式,許多GUI框架也是如此。
氣象站:
public class WeatherStation {
private String weather;
String[] weathers = {"下雨","下雪","下冰雹","出太陽"};
static List<BookWeather> list = new ArrayList<BookWeather>();
Random random = new Random();
public void startWork(){
new Thread(){
@Override public void run() { while(true){ updateWeather(); try { Thread.sleep(random.nextInt(1000)+500); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } public void updateWeather(){ weather = weathers[random.nextInt(4)]; System.out.println("天氣:"+ weather); }
public String getWeather() { return weather; } |
人:
public class Person implements BookWeather {
String name;
public Person(String name){ this.name = name; }
private WeatherStation station ;
public Person(String name,WeatherStation station){ this(name); this.station = station; }
//下雨","下雪 ","下冰雹","出太陽" @Override public void notifyWeather() { String weather = station.getWeather(); if("下雨".equals(weather)){ System.out.println(name+"打着雨傘上班"); }else if("下雪".equals(weather)){ System.out.println(name+"溜冰 上班"); }else if("下冰雹".equals(weather)){ System.out.println(name+"帶着頭盔 上班"); }else if("出太陽".equals(weather)){ System.out.println(name+"嗮着太陽 上班"); } }
} |
測試類:
public class Test {
public static void main(String[] args) throws InterruptedException { WeatherStation station = new WeatherStation(); station.startWork();
Person p1 = new Person("小明",station); while(true){ p1.notifyWeather(); Thread.sleep(2000); } } |
問題:天氣變化兩三次,小明才知道一次。
解決方案 :
package cn.itcast.test; import java.util.List; import java.util.ArrayList; import java.util.Random; public class WeatherStation {
private String weather;
String[] weathers = {"下雨","下雪","下冰雹","出太陽"};
private static List<BookWeather> list = new ArrayList<BookWeather>();
Random random = new Random();
public void addListaner(BookWeather e){ list.add(e); }
public void startWork(){
new Thread(){
@Override public void run() { while(true){ updateWeather(); try { Thread.sleep(random.nextInt(1000)+500); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } public void updateWeather(){ weather = weathers[random.nextInt(4)]; System.out.println("天氣:"+ weather); for(BookWeather item : list){ item.notifyWeather(weather); } }
public String getWeather() { return weather; } |
人:
public class Person implements BookWeather {
String name;
public Person(String name){ this.name = name; }
private WeatherStation station ;
public Person(String name,WeatherStation station){ this(name); this.station = station; }
//下雨","下雪 ","下冰雹","出太陽" @Override public void notifyWeather(String weather) { if("下雨".equals(weather)){ System.out.println(name+"打着雨傘上班"); }else if("下雪".equals(weather)){ System.out.println(name+"溜冰 上班"); }else if("下冰雹".equals(weather)){ System.out.println(name+"帶着頭盔 上班"); }else if("出太陽".equals(weather)){ System.out.println(name+"嗮着太陽 上班"); } }
|
}
接口:
public interface BookWeather {
public void notifyWeather(String weather); } |
public class Test {
public static void main(String[] args) throws InterruptedException { WeatherStation station = new WeatherStation(); station.startWork();
Person p1 = new Person("小明"); Person p2 = new Person("小紅"); Person p3 = new Person("小青 "); station.addListaner(p1); station.addListaner(p2); station.addListaner(p3);
} } |
Singleton
是指只能擁有一個實例的類就是單例類。
私有構造方法。
獲取方式
經過公共的靜態方法建立單一的實例。
兩種模式
懶漢模式 – 一般被稱爲延遲加載。注意存在線程安全問題.
餓漢模式
懶漢式的單例模式線程安全問題的解決方案:
class Single{
//聲明本類的一個私有的成員變量 private static Single single;
//第一步 : 私有化構造方法 private Single(){
} // 第三步:提供一個公共的方法獲取該類的實例對象 public static Single getInstance(){ if(single==null){ synchronized (single) { if(single==null){ single = new Single(); } } } return single; } } |
類字節碼文件是在硬盤上存儲的,是一個個的.class文件。咱們在new一個對象時,JVM會先把字節碼文件的信息讀出來放到內存中,第二次用時,就不用在加載了,而是直接使用以前緩存的這個字節碼信息。
字節碼的信息包括:類名、聲明的方法、聲明的字段等信息。在Java中「萬物皆對象」,這些信息固然也須要封裝一個對象,這就是Class類、Method類、Field類。
經過Class類、Method類、Field類等等類能夠獲得這個類型的一些信息,甚至能夠不用new關鍵字就建立一個實例,能夠執行一個對象中的方法,設置或獲取字段的值,這就是反射技術。
Java中有一個Class類用於表明某一個類的字節碼。
Java提供了三種方式獲取類的字節碼
forName()。forName方法用於加載某個類的字節碼到內存中,並使用class對象進行封裝
類名.class
對象.getClass()
/** * 加載類的字節碼的3種方式 * @throws Exception * */ public void test1() throws Exception { // 方式一 Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person"); // 方式二 Class clazz2 = Person.class; // 方式三 Person p1 = new Person(); Class clazz3 = p1.getClass(); } |
1. getName()類的名稱(全名,全限定名)
2 getSimpleName()類的的簡單名稱(不帶包名)
3. getModifiers(); 類的的修飾符
4.建立對象
無參數構造建立對象
newInstance()
5. 獲取指定參數的構造器對象,並可使用Constructor對象建立一個實例
Constructor<T> getConstructor(Class<?>... parameterTypes)
/** * 經過Class對象獲取類的一些信息 * * @throws Exception * */ private static void test2() throws Exception {
Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person"); // 獲取類的名稱 String name = clazz1.getName(); System.out.println(name); // cn.itcast.gz.reflect.Person // 獲取類的簡單名稱 System.out.println(clazz1.getSimpleName()); // Person // 獲取類的修飾符 int modifiers = clazz1.getModifiers(); System.out.println(modifiers); // 構建對象(默認調用無參數構造.) Object ins = clazz1.newInstance(); Person p = (Person) ins; System.out.println(p); // cn.itcast.gz.reflect.Person@c17164 // 獲取指定參數的構造函數 Constructor<?> con = clazz1.getConstructor(String.class, int.class); // 使用Constructor建立對象. Object p1 = con.newInstance("jack", 28); System.out.println(((Person) p1).getName()); } |
1.獲取公共方法包括繼承的父類的方法
getMethods()返回一個數組,元素類型是Method
2.獲取指定參數的公共方法
getMethod("setName", String.class);
3.得到全部的方法,包括私有
Method[] getDeclaredMethods()
4.得到指定參數的方法,包括私有
Method getDeclaredMethod(String name, Class<?>... parameterTypes)
/** * 獲取公有方法. * @throws Exception * */ private static void test3() throws Exception { Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person"); // 1.獲取非私用方法(包括父類繼承的方法) Method[] methods = clazz1.getMethods(); System.out.println(methods.length); for (Method m : methods) { // System.out.println(m.getName()); if ("eat".equals(m.getName())) { m.invoke(clazz1.newInstance(), null); } }
} |
/** * 獲取指定方法簽名的方法 * * @throws Exception * */ private static void test4() throws Exception { Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person"); // 獲取指定名稱的函數 Method method1 = clazz1.getMethod("eat", null); method1.invoke(new Person(), null); } |
/** * 獲取指定方法名且有參數的方法 * * @throws Exception * */ private static void test5() throws Exception { Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person"); Method method = clazz1.getMethod("eat", String.class); method.invoke(new Person(), "包子"); }
/** * 獲取指定方法名,參數列表爲空的方法. * * @throws Exception * */ private static void test4() throws Exception { Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person"); // 獲取指定名稱的函數 Method method1 = clazz1.getMethod("eat", null); method1.invoke(new Person(), null); } |
/** * 反射靜態方法 * @throws Exception * */ private static void test7() throws Exception { Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person"); Method method = clazz1.getMethod("play", null); method.invoke(null, null); }
/** * 訪問私有方法 暴力反射 * @throws Exception * */ private static void test6() throws Exception { Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person"); Method method = clazz1.getDeclaredMethod("movie", String.class); method.setAccessible(true); method.invoke(new Person(), "蒼老師"); }
|
1.獲取公共字段
Field[] getFields()
2.獲取指定參數的公共字段
Field getField(String name)
3.獲取全部的字段
Field[] getDeclaredFields()
4.獲取指定參數的字段,包括私用
Field getDeclaredField(String name)
/** * 獲取公有的字段 * */ private static void test8() throws Exception { Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person"); Field[] fields = clazz1.getFields(); Person p = new Person(); System.out.println(fields.length); for (Field f : fields) { System.out.println(f.getName()); if ("name".equals(f.getName())) { System.out.println(f.getType().getName()); f.set(p, "jack"); } } System.out.println(p.getName());
}
|
/** * 獲取私有的字段 * @throws Exception * */ private static void test9() throws Exception { Class clazz1 = Class.forName("cn.itcast.gz.reflect.Person"); Field field = clazz1.getDeclaredField("age"); System.out.println(field.getName()); field.setAccessible(true); Person p = new Person(); field.set(p, 100); System.out.println(p.getAge()); }
|
Factory
例如:汽車銷售商場
該模式將建立對象的過程放在了一個靜態方法中來實現.在實際編程中,若是須要大量的建立對象,該模式是比較理想的.
public class Demo1 { public static void main(String[] args) { System.out.println("買寶馬"); Car bmw = CarFactory("BMW"); bmw.run(); System.out.println("買大奔"); Car benz = CarFactory("Benz"); benz.run(); }
public static Car CarFactory(String carName) { if ("BMW".equals(carName)) { return new BMW(); } else if ("Benz".equals(carName)) { return new Benz(); } else { throw new RuntimeException("車型有誤"); } } }
abstract class Car {
public abstract void run(); }
class BMW extends Car {
@Override public void run() { System.out.println("BMW跑跑"); } }
class Benz extends Car {
@Override public void run() { System.out.println("Benz跑跑"); } } |
模擬spring工廠:
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Field; class Student{
private int id;
private String name;
public Student(int id , String name){ this.id = id; this.name = name; }
public Student(){
} public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; }
@Override public String toString() { return this.id +"-"+this.name; }
} class Person{
private int age;
public Person(){
}
@Override public String toString() { return this.age+""; } } public class Demo1 {
public static void main(String[] args) throws Exception { Object o = getInstance(); System.out.println(o);
}
public static Object getInstance() throws Exception{ FileReader fileReader = new FileReader("src/info.txt"); BufferedReader bufferedReader = new BufferedReader(fileReader); String line = bufferedReader.readLine(); Class clazz = Class.forName(line); Constructor c = clazz.getConstructor(null); Object c1 = c.newInstance(null); while((line=bufferedReader.readLine())!=null){ String[] datas = line.split("="); Field f = clazz.getDeclaredField(datas[0]); f.setAccessible(true); if(f.getType()==int.class){ f.set(c1, Integer.parseInt(datas[1])); }else{ //f.setAccessible(true); f.set(c1,datas[1]); } } return c1; }
} |