實例java
public class Example { String str = new String("hello"); char[] ch = {'a', 'b'}; public static void main(String[] args) { change(str, ch); System.out.println(str); //輸出:hello System.out.println(ch); //輸出:cd } public void change(String str, char[] ch) { str = "ok"; ch[0] = 'c'; //改變數據源內容 } }
使用場景
當咱們須要限制一系列變量的時候,一般想到數組或者集合;其實不少時候咱們須要限定變量須要作的事情不少,或者說若是被限制的變量能夠作其餘事情的話就更好了,而不是單純的一個變量,那麼,枚舉的做用不只僅可讓你使用限制在一個enum中的變量,而且這些變量的靈活性和拓展性很好。數據庫
public enum WeekEnums { //注:枚舉寫在最前面,不然編譯出錯 Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday; private static String getWeek(WeekEnums weekEnums) { String week = null; switch (weekEnums) { case Sunday://星期天 week = "星期天"; //此處寫邏輯處理代碼 break; case Monday://星期一 week = "星期一"; //此處寫邏輯處理代碼 break; case Tuesday:// 星期二 week = "星期二"; //此處寫邏輯處理代碼 break; case Wednesday://星期三 week = "星期三"; //此處寫邏輯處理代碼 break; case Thursday:// 星期四 week = "星期四"; //此處寫邏輯處理代碼 break; case Friday://星期五 week = "星期五"; //此處寫邏輯處理代碼 break; case Saturday:// 星期六 week = "星期六"; //此處寫邏輯處理代碼 break; } return week; } } //獲取方式: String weekday = WeekEnums.getWeek(WeekEnums.Friday);
ThreadLocal的內部結構編程
實例數組
//包含業務惟一標識的類 public class Context { private String transactionId; public String getTransactionId() { return transactionId; } public void setTransactionId(String transactionId) { this.transactionId = transactionId; } } // 其中引用了Context類 public class MyThreadLocal { private static final ThreadLocal<Context> userThreadLocal = new ThreadLocal<Context>(); public static void set(Context user){ userThreadLocal.set(user); } public static void unset(){ userThreadLocal.remove(); } public static Context get(){ return userThreadLocal.get(); } } //ThreadLocalDemo.java。生成並將業務標識設置到ThreadLocal中而後在業務方法中調用 public class ThreadLocalDemo implements Runnable{ private static AtomicInteger ai = new AtomicInteger(0); public void run() { Context context = new Context(); context.setTransactionId(getName()); MyThreadLocal.set(context); System.out.println("request["+Thread.currentThread().getName()+"]:"+context.getTransactionId()); new BusinessService().businessMethod(); MyThreadLocal.unset(); } private String getName() { return ai.getAndIncrement()+""; } public static void main(String[] args) { ThreadLocalDemo tld = new ThreadLocalDemo(); new Thread(tld).start(); new Thread(tld).start(); } } public class BusinessService { public void businessMethod() { Context context = MyThreadLocal.get(); System.out.println("service["+Thread.currentThread().getName()+"]:"+context.getTransactionId()); } }
實例安全
String s1 = "Hollis"; String s2 = new String("Hollis"); String s3 = new String("Hollis").intern(); System.out.println(s1 == s2); //輸出:false System.out.println(s1 == s3); //輸出:true
實例
定義一個字符串網絡
String s = "abcd";
圖解
使用變量來賦值變量數據結構
String s2 = s;
圖解
字符串鏈接多線程
s = s.concat("ef");
圖解
ide
可變參數
它容許一個方法把任意數量的值做爲參數。
可變參數的工做原理
可變參數在被使用的時候,他首先會建立一個數組,數組的長度就是調用該方法是傳遞的實參的個數,而後再把參數值所有放到這個數組當中,而後再把這個數組做爲參數傳遞到被調用的方法中。
實例函數
public static void main(String[] args) { print("a"); print("a", "b"); print("a", "b", "c"); } public static void print(String ... s){ for(String a: s) System.out.println(a); }
做用
用來作對象之間的比較的和對象排序。
Comparator實例
class Dog { int size; Dog(int s) { size = s; } } class SizeComparator implements Comparator<Dog> { @Override public int compare(Dog d1, Dog d2) { return d1.size - d2.size; } } public class ImpComparable { public static void main(String[] args) { TreeSet<Dog> d = new TreeSet<Dog>(new SizeComparator()); // pass comparator d.add(new Dog(1)); d.add(new Dog(2)); d.add(new Dog(1)); } }
Comparable實例
class Dog implements Comparable<Dog>{ int size; Dog(int s) { size = s; } @Override public int compareTo(Dog o) { return o.size - this.size; } } public class ImpComparable { public static void main(String[] args) { TreeSet<Dog> d = new TreeSet<Dog>(); d.add(new Dog(1)); d.add(new Dog(2)); d.add(new Dog(1)); } }
實例
class Dog{ public void bark(){ System.out.println("woof "); } //overloading method public void bark(int num){ for(int i=0; i<num; i++) System.out.println("woof "); } }
實例
class Dog{ public void bark(){ System.out.println("woof "); } } class Hound extends Dog{ public void sniff(){ System.out.println("sniff "); } public void bark(){ System.out.println("bowl"); } } public class OverridingTest{ public static void main(String [] args){ Dog dog = new Hound(); dog.bark(); } } //最終輸出:bowl
實例
//Q1:n*(n-1)*(n-2) = ? //遞歸 int factorial (int n) { if (n == 1) { return 1; } else { return n*factorial(n-1); } } //迭代 int factorial (int n) { int product = 1; for(int i=2; i<n; i++) { product *= i; } return product; } //Q2:fib(n-1) + fib(n-2) = ? //遞歸 int fib (int n) { if (n == 0) { return 0; } else if (n == 1) { return 1; } else { return fib(n-1) + fib(n-2); } } //迭代 int fib (int n) { int fib = 0; int a = 1; for(int i=0; i<n; i++) { int temp = fib; fib = fib + a; a = temp; } return fib; }
得到Class的三種方式
一、經過 Object 類中的 getClass() 方法,知道對象時用
Person p1 = new Person(); Class<?> c1 = p1.getClass();
二、直接經過 類名.class 的方式獲得,該方法最爲安全可靠,程序性能更高,說明任何一個類都有一個隱含的靜態成員變量 class,
Class<?> c2 = Person.class;
三、經過 Class 對象的 forName() 靜態方法來獲取,用的最多,但可能拋出 ClassNotFoundException 異常,主要用於動態代理。
Class<?> c3 = Class.forName("com.ys.reflex.Person");
經過反射獲取構造方法實例
package fanshe; public class Student { //---------------構造方法------------------- //(默認的構造方法) Student(String str){ System.out.println("(默認)的構造方法 s = " + str); } //無參構造方法 public Student(){ System.out.println("調用了公有、無參構造方法執行了。。。"); } //有一個參數的構造方法 public Student(char name){ System.out.println("姓名:" + name); } //有多個參數的構造方法 public Student(String name ,int age){ System.out.println("姓名:"+name+"年齡:"+ age);//這的執行效率有問題,之後解決。 } //受保護的構造方法 protected Student(boolean n){ System.out.println("受保護的構造方法 n = " + n); } //私有構造方法 private Student(int age){ System.out.println("私有的構造方法 年齡:"+ age); } } //測試類 package fanshe; import java.lang.reflect.Constructor; public class Constructors { public static void main(String[] args) throws Exception { //1.加載Class對象 Class clazz = Class.forName("fanshe.Student"); //2.獲取全部公有構造方法 System.out.println("**********************全部公有構造方法*********************************"); Constructor[] conArray = clazz.getConstructors(); for(Constructor c : conArray){ System.out.println(c); } System.out.println("************全部的構造方法(包括:私有、受保護、默認、公有)***************"); conArray = clazz.getDeclaredConstructors(); for(Constructor c : conArray){ System.out.println(c); } System.out.println("*****************獲取公有、無參的構造方法*******************************"); Constructor con = clazz.getConstructor(null); //1>、由於是無參的構造方法因此類型是一個null,不寫也能夠:這裏須要的是一個參數的類型,切記是類型 //2>、返回的是描述這個無參構造函數的類對象。 System.out.println("con = " + con); //調用構造方法 Object obj = con.newInstance(); // System.out.println("obj = " + obj); // Student stu = (Student)obj; System.out.println("******************獲取私有構造方法,並調用*******************************"); con = clazz.getDeclaredConstructor(char.class); System.out.println(con); //調用構造方法 con.setAccessible(true);//暴力訪問(忽略掉訪問修飾符) obj = con.newInstance('男'); } }
獲取成員變量實例
package fanshe.field; public class Student { public Student(){ } //**********字段*************// public String name; protected int age; char sex; private String phoneNum; @Override public String toString() { return "Student [name=" + name + ", age=" + age + ", sex=" + sex + ", phoneNum=" + phoneNum + "]"; } } //測試類 package fanshe.field; import java.lang.reflect.Field; public class Fields { public static void main(String[] args) throws Exception { //1.獲取Class對象 Class stuClass = Class.forName("fanshe.field.Student"); //2.獲取字段 System.out.println("************獲取全部公有的字段********************"); Field[] fieldArray = stuClass.getFields(); for(Field f : fieldArray){ System.out.println(f); } System.out.println("************獲取全部的字段(包括私有、受保護、默認的)********************"); fieldArray = stuClass.getDeclaredFields(); for(Field f : fieldArray){ System.out.println(f); } System.out.println("*************獲取公有字段**並調用***********************************"); Field f = stuClass.getField("name"); System.out.println(f); //獲取一個對象 Object obj = stuClass.getConstructor().newInstance();//產生Student對象--》Student stu = new Student(); //爲字段設置值 f.set(obj, "劉德華");//爲Student對象中的name屬性賦值--》stu.name = "劉德華" //驗證 Student stu = (Student)obj; System.out.println("驗證姓名:" + stu.name); System.out.println("**************獲取私有字段****並調用********************************"); f = stuClass.getDeclaredField("phoneNum"); System.out.println(f); f.setAccessible(true);//暴力反射,解除私有限定 f.set(obj, "18888889999"); System.out.println("驗證電話:" + stu); } }
獲取成員方法實例
package fanshe.method; public class Student { //**************成員方法***************// public void show1(String s){ System.out.println("調用了:公有的,String參數的show1(): s = " + s); } protected void show2(){ System.out.println("調用了:受保護的,無參的show2()"); } void show3(){ System.out.println("調用了:默認的,無參的show3()"); } private String show4(int age){ System.out.println("調用了,私有的,而且有返回值的,int參數的show4(): age = " + age); return "abcd"; } } //測試類 package fanshe.method; import java.lang.reflect.Method; public class MethodClass { public static void main(String[] args) throws Exception { //1.獲取Class對象 Class stuClass = Class.forName("fanshe.method.Student"); //2.獲取全部公有方法 System.out.println("***************獲取全部的」公有「方法*******************"); stuClass.getMethods(); Method[] methodArray = stuClass.getMethods(); for(Method m : methodArray){ System.out.println(m); } System.out.println("***************獲取全部的方法,包括私有的*******************"); methodArray = stuClass.getDeclaredMethods(); for(Method m : methodArray){ System.out.println(m); } System.out.println("***************獲取公有的show1()方法*******************"); Method m = stuClass.getMethod("show1", String.class); System.out.println(m); //實例化一個Student對象 Object obj = stuClass.getConstructor().newInstance(); m.invoke(obj, "劉德華"); System.out.println("***************獲取私有的show4()方法******************"); m = stuClass.getDeclaredMethod("show4", int.class); System.out.println(m); m.setAccessible(true);//解除私有限定 Object result = m.invoke(obj, 20);//須要兩個參數,一個是要調用的對象(獲取有反射),一個是實參 System.out.println("返回值:" + result); } }
經過反射運行配置文件內容實例
public class Student { public void show(){ System.out.println("is show()"); } }
配置文件以txt文件爲例子(pro.txt):
className = cn.fanshe.Student methodName = show
測試類:
import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.lang.reflect.Method; import java.util.Properties; public class Demo { public static void main(String[] args) throws Exception { //經過反射獲取Class對象 Class stuClass = Class.forName(getValue("className"));//"cn.fanshe.Student" //2獲取show()方法 Method m = stuClass.getMethod(getValue("methodName"));//show //3.調用show()方法 m.invoke(stuClass.getConstructor().newInstance()); } //此方法接收一個key,在配置文件中獲取相應的value public static String getValue(String key) throws IOException{ Properties pro = new Properties();//獲取配置文件的對象 FileReader in = new FileReader("pro.txt");//獲取輸入流 pro.load(in);//將流加載到配置文件對象中 in.close(); return pro.getProperty(key);//返回根據key獲取的value值 } }
當咱們升級這個系統時,不要Student類,而須要新寫一個Student2的類時,這時只須要更改pro.txt的文件內容就能夠了。代碼就一點不用改動
public class Student2 { public void show2(){ System.out.println("is show2()"); } }
配置文件更改成:
className = cn.fanshe.Student2 methodName = show2