实例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