source:http://blog.java1234.com/index.html?typeId=1
泛型引入
定义:使用泛型可以指代任意对象类型;
/** * 定义泛型类 * @author caofeng * * @param <T> */ public class CC<T>{ private T ob; public CC(T ob) { super(); this.ob = ob; } public T getOb() { return ob; } public void setOb(T ob) { this.ob = ob; } /** * 打印T的类型 */ public void print(){ System.out.println("T的实际类型是:"+ob.getClass().getName()); } }
用<T>指代任意类型,当然也可以用其他字母,但是一般用T,Type的意思;
public class Test1{ public static void main(String[] args) { // begin test c1 C1 c1=new C1(1); c1.print(); int i=c1.getA(); System.out.println("i="+i); // end test c1 // begin test c2 C2 c2=new C2("Hi"); c2.print(); String s1=c2.getA(); System.out.println("s1="+s1); // end test c2 // begin test c12 C12 c12=new C12(1); // 向上转型 c12.print(); int i12=(Integer) c12.getObject(); // 向下转型 System.out.println("i12="+i12); C12 c122=new C12("你好");// 向上转型 c122.print(); String s122=(String) c122.getObject(); // 向下转型 System.out.println("s122="+s122); // end test c12 // begin test CC CC<Integer> cc=new CC<Integer>(1); cc.print(); int icc=cc.getOb(); System.out.println("icc="+icc); CC<String> cc2=new CC<String>("我是泛型,好简单啊"); cc2.print(); String icc2=cc2.getOb(); System.out.println("icc2="+icc2); // end test CC } }
运行输出:
a的类型是:java.lang.Integer
i=1
a的类型是:java.lang.String
s1=Hi
object的类型是:java.lang.Integer
i12=1
object的类型是:java.lang.String
s122=你好
T的实际类型是:java.lang.Integer
icc=1
T的实际类型是:java.lang.String
icc2=我是泛型,好简单啊
限制泛型类型
public class Animal { public void print(){ System.out.println("动物"); } } public class Dog extends Animal{ public void print(){ System.out.println("Dog"); } } public class Cat extends Animal{ public void print(){ System.out.println("Cat"); } } public class Demo <T extends Animal>{ private T ob; public T getOb() { return ob; } public void setOb(T ob) { this.ob = ob; } public Demo(T ob) { super(); this.ob = ob; } public void print(){ System.out.println("T的类型是:"+ob.getClass().getName()); } }
public class Test { public static void main(String[] args) { Demo<Dog> demo=new Demo<Dog>(new Dog()); Dog dog=demo.getOb(); dog.print(); Demo<Cat> demo2=new Demo<Cat>(new Cat()); Cat cat=demo2.getOb(); cat.print(); Demo<Animal> demo3=new Demo<Animal>(new Animal()); } }
运行输出:
Dog
Cat
通配符泛型
通配符泛型在使用泛型 特殊的场景下用到,比如把泛型对象作为方法参数传入方法的时候,就用到通配符泛型;
public class Test { /** * 通配符泛型 * @param a */ private static void take(Demo<?> a){ a.print(); } public static void main(String[] args) { Demo<Dog> dog=new Demo<Dog>(new Dog()); take(dog); Demo<Cat> cat=new Demo<Cat>(new Cat()); take(cat); Demo<Animal> animal=new Demo<Animal>(new Animal()); take(animal); } }
泛型方法指返回值和参数都用泛型表示的方法;
public class Test { /** * 泛型方法 * @param t */ public static <T> void f(T t){ System.out.println("T的类型是:"+t.getClass().getName()); } public static void main(String[] args) { f(""); f(1); f(1.0f); f(new Object()); } }
运行输出:
T的类型是:java.lang.String
T的类型是:java.lang.Integer
T的类型是:java.lang.Float
T的类型是:java.lang.Object
反射
一般情况下,我们知道一个类,那可定可以通过这个类创建对象;
但是如果要求通过一个对象找到一个类,这时候反射就派上用场了。
java反射实现的核心就是Class类 java.lang包下的。
java Class基本使用
通过Class类获取对象完整包类名:
public class Test { public static void main(String[] args) { Student student=new Student(); System.out.println(student.getClass().getName()); } }
对象.getClass() 调用的是Object类的getClass() 得到Class对象 然后再调用Class里的getName()方法,获取到完整包路径类;
通过完整包路径类型来实例化Class对象:
public class Test { public static void main(String[] args) { try { Class<?> c=Class.forName("com.java.Student"); System.out.println(c.getName()); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
通过完整包路径类型来实例化Class对象,再通过Class对象获取Student类实例:
public class Student { private String name; private Integer age; public Student(String name, Integer age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } } public class Test{ public static void main(String[] args) { Class<?> c=null; try { c=Class.forName("com.java.Student"); System.out.println(c.getName()); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } Student s=null; Constructor<?>[] cons=c.getConstructors(); try { s=(Student) cons[0].newInstance("小三",21); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(s); } }
运行输出:
com.java1234.chap07.sec01.Student
Student [name=小三, age=21]
通过反射获取类的基本结构
1,通过getConstructors()方法获取所有构造方法:
public static void main(String[] args) { Class<?> c=null; try { c=Class.forName("com.java.Student"); System.out.println(c.getName()); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } Constructor<?> cons[]=c.getConstructors(); for(Constructor<?> con:cons){ System.out.println("构造方法:"+con); } }
运行输出:
com.java.Student
构造方法:public com.java.Student(java.lang.String)
构造方法:public com.java.Student(java.lang.String,java.lang.Integer)
2,通过getMethods()方法获取所有方法:
public static void main(String[] args) { Class<?> c=null; try { c=Class.forName("com.java.Student"); System.out.println(c.getName()); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } Method mds[]=c.getMethods(); for(Method m:mds){ System.out.println(m); } }
运行输出:
com.java.Student
public java.lang.String com.java.Student.toString()
public java.lang.String com.java.Student.getName()
public void com.java.Student.setName(java.lang.String)
public java.lang.Integer com.java.Student.getAge()
public void com.java.Student.setAge(java.lang.Integer)
public void com.java.Student.say()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
3,通过getDeclaredFields()方法获取所有属性:
public static void main(String[] args) { Class<?> c=null; try { c=Class.forName("com.java.Student"); System.out.println(c.getName()); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } Field fs[]=c.getDeclaredFields(); for(Field f:fs){ System.out.println(f); } }
运行输出:
com.java.Student
private java.lang.String com.java.Student.name
private java.lang.Integer com.java.Student.age
通过反射调用方法和操作属性
Student类:
public class Student { private String name; private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public void say(){ System.out.println("我的姓名:"+name); } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }
1,通过反射调用方法,主要通过invoke方法:
import java.lang.reflect.Method; public class Test { public static void main(String[] args) { Class<?> c=null; try { c=Class.forName("com.java.Student"); System.out.println(c.getName()); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { Object obj=c.newInstance(); Method m2=obj.getClass().getMethod("setName", String.class); m2.invoke(obj, "小三"); Method m=obj.getClass().getMethod("getName"); String name=(String) m.invoke(obj); System.out.println("name="+name); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
2,通过反射操作属性,java里反射可以操作私有属性,只需要设置下:
import java.lang.reflect.Field; public class Test { public static void main(String[] args) { Class<?> c=null; try { c=Class.forName("com.java.Student"); System.out.println(c.getName()); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { Object obj=c.newInstance(); Field nameField=c.getDeclaredField("name"); nameField.setAccessible(true); nameField.set(obj, "小三"); System.out.println("name="+nameField.get(obj)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
运行输出:
com.java.Student
name=小三
//1,通过反射获取类所实现的所有接口 //2,通过反射获取父类 public class Student extends A implements B,C{ } //获取接口 public class Test { public static void main(String[] args) { Class<?> c=null; try { c=Class.forName("com.java.Student"); System.out.println(c.getName()); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } Class<?> []ifs= c.getInterfaces(); for(Class<?> i:ifs){ System.out.println(i); } } } //获取父类 public class Test2 { public static void main(String[] args) { Class<?> c=null; try { c=Class.forName("com.java.Student"); System.out.println(c.getName()); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } Class<?> s=c.getSuperclass(); System.out.println(s); } }
集合
Collection接口是集合的老祖宗,定义了接口的基本方法;
List是Collection接口的子接口,也是最常用的接口,此接口对Collection接口进行了大量的扩展,List集合里的元素是可以重复的;
List接口的主要实现类有ArrayList,和LinkedList。
在数据量不大的情况下,这两个类性能差别不大,
一般情况下,集合里的元素很少变化的,一般用ArrayList,
假如集合里元素经常变动,要用LinkedList;底层实现有差别的。
import java.util.ArrayList; public class TestArrayLit { private static void pringArrayList(ArrayList<String> arrayList){ System.out.println("当前的集合元素:"); for(int i=0;i<arrayList.size();i++){ System.out.println(arrayList.get(i)); } } public static void main(String[] args) { ArrayList<String> arrayList=new ArrayList<String>(); // 添加元素 arrayList.add("张三"); arrayList.add("李四"); pringArrayList(arrayList); // 在指定位置插入元素 arrayList.add(1, "小张三"); pringArrayList(arrayList); // 元素的替换 arrayList.set(2, "小李四"); pringArrayList(arrayList); // 移除元素 arrayList.remove(0); pringArrayList(arrayList); } }
import java.util.LinkedList; public class TestLinkedList { private static void pringLinkedList(LinkedList<String> linkedList){ System.out.println("当前元素的集合:"); for(int i=0;i<linkedList.size();i++){ System.out.print(linkedList.get(i)+" "); } System.out.println(); } public static void main(String[] args) { LinkedList<String> linkedList=new LinkedList<String>(); linkedList.add("张三"); linkedList.add("李四"); linkedList.add("王五"); linkedList.add("李四"); linkedList.add("赵六"); pringLinkedList(linkedList); // indexOf 寻找位置 System.out.println(linkedList.indexOf("李四")); pringLinkedList(linkedList); // peekFirst 获取第一个元素 System.out.println(linkedList.peekFirst()); pringLinkedList(linkedList); // peekLast 获取最后一个元素 System.out.println(linkedList.peekLast()); pringLinkedList(linkedList); // pollFirst 摘取第一个元素 System.out.println(linkedList.pollFirst()); pringLinkedList(linkedList); // pollLast 榨取最后一个元素 System.out.println(linkedList.pollLast()); pringLinkedList(linkedList); } }
集合的遍历
Iterator遍历器:
public class Student { private String name; private Integer age; public Student() { super(); // TODO Auto-generated constructor stub } public Student(String name, Integer age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
import java.util.Iterator; import java.util.LinkedList; public class TestIterator { public static void main(String[] args) { LinkedList<Student> list=new LinkedList<Student>(); list.add(new Student("张三",10)); list.add(new Student("李四",20)); list.add(new Student("王五",30)); /** * 用Iterator遍历集合 */ Iterator<Student> it=list.iterator(); // 返回一个迭代器 while(it.hasNext()){ Student s=it.next(); // 返回迭代的下一个元素。 System.out.println("姓名:"+s.getName()+"年龄:"+s.getAge()); } } }
运行输出:
姓名:张三年龄:10
姓名:李四年龄:20
姓名:王五年龄:30
foreach遍历:
import java.util.LinkedList; public class TestForeach { public static void main(String[] args) { LinkedList<Student> list=new LinkedList<Student>(); list.add(new Student("张三",10)); list.add(new Student("李四",20)); list.add(new Student("王五",30)); /** * 用foreach遍历 */ for(Student s:list){ System.out.println("姓名:"+s.getName()+"年龄:"+s.getAge()); } } }
运行输出:
姓名:张三年龄:10
姓名:李四年龄:20
姓名:王五年龄:30
Set集合
Set集合是Collection接口的子接口,没有对Collection接口进行扩展,里面不允许存在重复的内容;
import java.util.HashSet; import java.util.Iterator; public class TestHashSet { public static void main(String[] args) { /** * 1,HashSet是无序 * 2,不循序有重复的值 */ HashSet<String> hs=new HashSet<String>(); hs.add("21221"); hs.add("112"); hs.add("312"); hs.add("421"); hs.add("312"); /** * 用Iterator遍历集合 */ Iterator<String> it=hs.iterator(); while(it.hasNext()){ String s=it.next(); System.out.println(s+" "); } } }
运行输出:
112
421
312
21221
Map集合
是存放一对值的最大接口,即接口中的每一个元素都是一对,以key->value键值对的形式保存;
import java.util.HashMap; import java.util.Iterator; public class TestHashMap { public static void main(String[] args) { HashMap<String,Student> hashMap=new HashMap<String,Student>(); hashMap.put("1号", new Student("张三",10)); hashMap.put("2号", new Student("李四",20)); hashMap.put("3号", new Student("王五",30)); // 通过key,获取value Student s=hashMap.get("1号"); System.out.println(s.getName()+":"+s.getAge()); Iterator<String> it=hashMap.keySet().iterator(); // 获取key的集合,再获取迭代器 while(it.hasNext()){ String key=it.next(); // 获取key Student student=hashMap.get(key); // 通过key获取value System.out.println("key="+key+" value=["+student.getName()+","+student.getAge()+"]"); } } }
运行输出:
张三:10
key=3号 value=[王五,30]
key=2号 value=[李四,20]
key=1号 value=[张三,10]
Java多线程
定义:同时对多项任务加以控制;
程序里同时执行多个任务并且加以控制 这个是java多线程的含义。同时干多个事,能充分利用cpu 内存等硬件设备,提高程序运行效率。
public class Eat extends Thread{ @Override public void run() { for(int i=0;i<100;i++){ try { Thread.sleep(100); System.out.println("吃饭"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public class Music extends Thread{ @Override public void run() { for(int i=0;i<100;i++){ try { Thread.sleep(100); System.out.println("听音乐"); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } public class Test { public static void main(String[] args) { Music musicThread=new Music(); Eat eatThread=new Eat(); musicThread.start(); eatThread.start(); } }
Java多线程实现
//1,继承Thread类 public class Thread1 extends Thread{ private int baoZi=1; private String threadName; public Thread1(String threadName) { super(); this.threadName = threadName; } @Override public void run() { while(baoZi<=10){ System.out.println(threadName+" 吃"+baoZi+"第个包子"); baoZi++; } } public static void main(String[] args) { // 张三 李四一起吃包子 每人吃10个 Thread1 t1=new Thread1("张三线程"); Thread1 t2=new Thread1("李四线程"); t1.start(); t2.start(); } } //2,实现Runnable接口 public class Thread2 implements Runnable{ private int baoZi=1; private String threadName; public Thread2(String threadName) { super(); this.threadName = threadName; } @Override public void run() { while(baoZi<=10){ System.out.println(threadName+" 吃"+baoZi+"第个包子"); baoZi++; } } public static void main(String[] args) { // 张三 李四一起吃包子 每人吃10个 Thread2 t1=new Thread2("张三线程"); Thread2 t2=new Thread2("李四线程"); Thread t11=new Thread(t1); Thread t12=new Thread(t2); t11.start(); t12.start(); } } //3,多线程实现数据共享 public class Thread3 implements Runnable{ private int baoZi=1; private String threadName; public Thread3(String threadName) { super(); this.threadName = threadName; } //run方法要加synchronized锁,否则会出现多个线程同时进入方法的情况,导致多个线程吃同一个包子 @Override public synchronized void run() { while(baoZi<=10){ System.out.println(threadName+" 吃"+baoZi+"第个包子"); baoZi++; } } public static void main(String[] args) { Thread3 t1=new Thread3("超级张三线程"); Thread t11=new Thread(t1); Thread t12=new Thread(t1); Thread t13=new Thread(t1); t11.start(); t12.start(); t13.start(); } }
线程的状态
总的执行图:
所有状态:
1,创建状态
在程序中用构造方法创建了一个线程对象后,新的线程对象便处于新建状态,此时,它已经有了相应的
内存空间和其他资源,但还处于不可运行状态。新建一个线程对象可采用Thread 类的构造方法来实现,例
如,“Thread thread=new Thread();”。
2,就绪状态
新建线程对象后,调用该线程的start()方法就可以启动线程。当线程启动时,线程进入就绪状态。此时,
线程将进入线程队列排队,等待CPU 服务,这表明它已经具备了运行条件。
3,运行状态
当就绪状态的线程被调用并获得处理器资源时,线程就进入了运行状态。此时,自动调用该线程对象
的run()方法。run()方法定义了该线程的操作和功能。
4,堵塞状态
一个正在执行的线程在某些特殊情况下,如被人为挂起或需要执行耗时的输入/输出操作时,将让出
CPU 并暂时中止自己的执行,进入堵塞状态。堵塞时,线程不能进入排队队列,只有当引起堵塞的原因被
消除后,线程才可以转入就绪状态。
5,死亡状态
线程调用stop()方法时或run()方法执行结束后,即处于死亡状态。处于死亡状态的线程不具有继续运
行的能力。
线程常用方法
1,getName(); 返回该线程的名称。
2,currentThread();返回对当前正在执行的线程对象的引用。
3,isAlive();测试线程是否处于活动状态。
4,sleep();线程休眠。
5,setPriority(int newPriority);更改线程的优先级。
6,yield();暂停当前正在执行的线程对象,并执行其他线程。
public class Demo1 implements Runnable{ @Override public void run() { // TODO Auto-generated method stub for(int i=0;i<10;i++){ // 获取当前线程 Thread t=Thread.currentThread(); System.out.println(t.getName()+":"+i); // 返回线程的名称 } } public static void main(String[] args) { Demo1 demo1=new Demo1(); new Thread(demo1).start(); new Thread(demo1).start(); new Thread(demo1,"线程3").start(); } } public class Demo2 implements Runnable{ @Override public void run() { // TODO Auto-generated method stub for(int i=0;i<10;i++){ // 获取当前线程 Thread t=Thread.currentThread(); System.out.println(t.getName()+":"+i); // 返回线程的名称 } } public static void main(String[] args) { Demo2 demo2=new Demo2(); Thread t1=new Thread(demo2); System.out.println("t1是否活动:"+t1.isAlive()); t1.start(); System.out.println("t1是否活动:"+t1.isAlive()); } } public class Demo3 implements Runnable{ @Override public void run() { // TODO Auto-generated method stub for(int i=0;i<10;i++){ try { Thread.sleep(1000); // 获取当前线程 Thread t=Thread.currentThread(); System.out.println(t.getName()+":"+i); // 返回线程的名称 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { Demo3 demo1=new Demo3(); new Thread(demo1).start(); } } public class Demo4 implements Runnable{ @Override public void run() { // TODO Auto-generated method stub for(int i=0;i<10;i++){ try { Thread.sleep(1000); // 获取当前线程 Thread t=Thread.currentThread(); System.out.println(t.getName()+":"+i); // 返回线程的名称 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { Demo4 demo4=new Demo4(); Thread t1=new Thread(demo4,"线程A"); Thread t2=new Thread(demo4,"线程B"); Thread t3=new Thread(demo4,"线程C"); t1.setPriority(Thread.MAX_PRIORITY); t2.setPriority(Thread.MIN_PRIORITY); t3.setPriority(Thread.NORM_PRIORITY); t3.start(); t1.start(); t2.start(); } } public class Demo5 implements Runnable{ @SuppressWarnings("static-access") @Override public void run() { // TODO Auto-generated method stub for(int i=0;i<10;i++){ try { Thread.sleep(100); // 获取当前线程 Thread t=Thread.currentThread(); System.out.println(t.getName()+":"+i); // 返回线程的名称 if(i==5){ System.out.println("线程礼让:"); Thread.currentThread().yield(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void main(String[] args) { Demo5 demo1=new Demo5(); new Thread(demo1,"线程A").start(); new Thread(demo1,"线程B").start(); } }
线程同步
//method1 public class Thread3 implements Runnable{ private int baoZi=1; private String threadName; public Thread3(String threadName) { super(); this.threadName = threadName; } @Override public synchronized void run() { while(baoZi<=10){ System.out.println(threadName+" 吃第"+baoZi+"个包子"); baoZi++; } } public static void main(String[] args) { Thread3 t1=new Thread3("超级张三线程"); Thread t11=new Thread(t1); Thread t12=new Thread(t1); Thread t13=new Thread(t1); t11.start(); t12.start(); t13.start(); } } //method2 public class Thread4 implements Runnable{ private int baoZi=1; private String threadName; public Thread4(String threadName) { super(); this.threadName = threadName; } @Override public void run() { /** * 同步块 */ synchronized (this) { while(baoZi<=10){ System.out.println(threadName+" 吃第"+baoZi+"个包子"); baoZi++; } } } public static void main(String[] args) { Thread4 t1=new Thread4("超级张三线程"); Thread t11=new Thread(t1); Thread t12=new Thread(t1); Thread t13=new Thread(t1); t11.start(); t12.start(); t13.start(); } }