Java学习笔记下篇(atguigu)

目录

6 异常处理

7 集合

8 泛型

9 枚举类和注解

10 IO流

11 多线程

12 常用类

13 反射机制

14 网络编程


6 异常处理

1.体系结构
   java.lang.Object
           |----java.lang.Throwable
                    |-------java.lang.Error:错误,java程序对此无能为力,不显式的处理
                    |-------java.lang.Exception:异常。需要进行处理
                                    |------RuntimeException:运行时异常
                                             |-----ArrayIndexOutOfBoundsException/NullPointerException/ArithmeticException/ClassCastException
                                    |------非RuntimeException:编译时异常
               
2.因为java程序分为javac.exe和java.exe两个过程,在每个过程中,都有可能出现异常。故分为编译时异常、运行时异常
  2.1 对于运行时异常比较常见,可以不显式的来处理。
  2.2 对于编译时异常,必须要显式的处理
        编译时异常,不是说有异常才处理,而是存在异常的隐患,必须在编译前,提示程序,万一出现异常,如何处理!

2.如何处理异常?
   java 中的“抓抛模型”
 * 1."抛":当我们执行代码时,一旦出现异常,就会在异常的代码处生成一个对应的异常类型的对象,并
 *        将此对象抛出。(自动抛出   / 手动抛出)
 *        >一旦抛出此异常类的对象,那么程序就终止执行
 *        >此异常类的对象抛给方法的调用者。
 * 2."抓":抓住上一步抛出来的异常类的对象。如何抓?即为异常处理的方式
 *    java 提供了两种方式用来处理一个异常类的对象。
 *    处理的方式一:
 *    try{
 *        //可能出现异常的代码
 *    }catch(Exception1 e1){
 *        //处理的方式1
 *    }catch(Exception2 e2){
 *        //处理的方式2
 *    }finally{
 *        //一定要执行的代码 
 *    }
 * 注:1.try内声明的变量,类似于局部变量,出了try{}语句,就不能被调用
 *    2.finally是可选的。
 *    3.catch语句内部是对异常对象的处理:
 *        >getMessage();  printStackTrace();
 *    4.可以有多个catch语句,try中抛出的异常类对象从上往下去匹配catch中的异常类的类型,一旦满足
 *      就执行catch中的代码。执行完,就跳出其后的多条catch语句
 *    5.如果异常处理了,那么其后的代码继续执行。
 *    6.若catch中多个异常类型是"并列"关系,孰上孰下都可以。
 *      若catch中多个异常类型是"包含"关系,须将子类放在父类的上面,进行处理。否则报错!
 *    7.finally中存放的是一定会被执行的代码,不管try中、catch中是否仍有异常未被处理,以及是否有return语句。
 *    8.try-catch是可以嵌套的。
    处理方式二:
     在方法的声明处,显式的使用throws + 异常类型
     public void method1()  throws Exception1 e1,Exception2 e2{
        //可能出现异常(尤其是编译时异常,一定要处理)
     }
    
    public void method2() throws Exception1 e1,Exception2 e2{
        method1();
    }

     public void method3(){
    try{
        method2();
     }catch(Exception1 e1){
        System.out.println(e1.getMessage());    
    }catch(Exception2 e2){
        System.out.println(e2.getMessage());    
    }

     }

   public static void main(String[] args){
    对象1.method3();//不会再出现上述的Exception1和Exception2的异常!
   }
3.如何手动的抛出一个异常?
   在方法的内部,可以使用  throw + 异常类对象,来手动的抛出一个异常!

        //比较两个圆的半径的大小。
    public int compareTo(Object obj) throws Exception{
        if(this == obj){
            return 0;
        }
        else if(obj instanceof Circle){
            Circle c = (Circle)obj;
            if(this.radius > c.radius){
                return 1;
            }else if(this.radius == c.radius){
                return 0;
            }else{
                return -1;
            }
        }else{
            //return -2;
            //手动的抛出一个异常
            //throw new Exception("传入的类型有误!");
            //throw new String("传入的类型有误!");
            throw new MyException("传入的类型有误!");
        }
    }
4.如何自定义一个异常类?
>手动的抛出一个异常,除了抛出的是现成的异常类的对象之外,还可以抛出一个自定义的异常类的对象!
>如何自定义一个异常类呢?
//1.自定义的异常类继承现有的异常类
//2.提供一个序列号,提供几个重载的构造器
public class MyException extends Exception{
    
    static final long serialVersionUID = -70348975766939L;
    
    public MyException(){
        
    }
    public MyException(String msg){
        super(msg);
    }
}
5.“5个关键字搞定异常处理!”  其中,要区分:throw与throws的区别?

7 集合

1.对象的存储:①数组(基本数据类型  & 引用数据类型)  ②集合(引用数据类型)
    >数组存储数据的弊端:长度一旦初始化以后,就不可变;真正给数组元素赋值的个数没有现成的方法可用。
2.集合框架
Collection接口 :方法:①add(Object obj),addAll(Collection coll),size(),clear(),isEmpty();
                    ②remove(Object obj),removeAll(Collection coll),retainAll(Collection coll),equals(Object obj),contains(Object obj)
                        containsAll(Collection coll),hashCode()
                     ③ iterator(),toArray();
 *             |------List接口:存储有序的,可以重复的元素.---相当于“动态”数组
            >新增的方法:删除remove(int index) 修改set(int index,Object obj) 获取get(int index)插入add(int index,Object obj)

            >添加进List集合中的元素(或对象)所在的类一定要重写equals()方法
 *                        |------ArrayList(主要的实现类)
                          |------LinkedList(更适用于频繁的插入、删除操作)
                          |------Vector(古老的实现类、线程安全的,但效率要低于ArrayList)
 *             |------Set接口:存储无序的,不可重复的元素。---相当于高中的“集合”概念
            >Set使用的方法基本上都是Collection接口下定义的。
            >添加进Set集合中的元素所在的类一定要重写equals() 和 hashCode()。要求重写equals() 和 hashCode()方法保持一致。
            >1.无序性:无序性!= 随机性。真正的无序性,指的是元素在底层存储的位置是无序的。
            >2.不可重复性:当向Set中添加进相同的元素的时候,后面的这个不能添加进去。

 *                        |------HashSet(主要的实现类)
                           |------LinkedHashSet(是HashSet的子类,当我们遍历集合元素时,是按照添加进去的顺序实现的;频繁的遍历,较少的添加、插入操作建议选择此)
                           |------TreeSet(可以按照添加进集合中的元素的指定属性进行排序)
                        >要求TreeSet添加进的元素必须是同一个类的!
                        >两种排序方式:自然排序:①要求添加进TreeSet中的元素所在的类implements Comparable接口
                                            ②重写compareTo(Object obj),在此方法内指明按照元素的哪个属性进行排序
                                            ③向TreeSet中添加元素即可。若不实现此接口,会报运行时异常
                                     定制排序:①创建一个实现Comparator接口的实现类的对象。在实现类中重写Comparator的compare(Object o1,Object o2)方法
                                            ②在此compare()方法中指明按照元素所在类的哪个属性进行排序
                                            ③将此实现Comparator接口的实现类的对象作为形参传递给TreeSet的构造器中
                                            ④向TreeSet中添加元素即可。若不实现此接口,会报运行时异常
                        >要求重写的compareTo()或者compare()方法与equals()和hashCode()方法保持一致。
Map接口:存储“键-值”对的数据 ----相当于高中的“函数y = f(x)” (x1,y1)  (x2,y2)
>key是不可重复的,使用Set存放。value可以重复的,使用Collection来存放的。一个key-value对构成一个entry(Map.Entry),entry使用Set来存放。
>添加、修改 put(Object key,Object value)  删除remove(Object key)  获取get(Object key) size() / keySet() values()  entrySet()

 *             |-----HashMap:主要的实现类,可以添加null键,null值
               |-----LinkedHashMap:是HashMap的子类,可以按照添加进Map的顺序实现遍历
               |-----TreeMap:需要按照key所在类的指定属性进行排序。要求key是同一个类的对象。对key考虑使用自然排序 或 定制排序
               |-----Hashtable:是一个古老的实现类,线程安全的,不可以添加null键,null值不建议使用。
               |-----子类:Properties:常用来处理属性文件

Iterator接口:用来遍历集合Collection元素

Collections工具类:操作Collection及Map的工具类,大部分为static的方法。

附:Properties的使用
Properties pros = new Properties();
        pros.load(new FileInputStream(new File("jdbc.properties")));
        String user = pros.getProperty("user");
        System.out.println(user);
        String password = pros.getProperty("password");
        System.out.println(password);                

8 泛型

1.泛型在集合中的使用(掌握)
2.自定义泛型类、泛型接口、泛型方法(理解 --->使用)
3.泛型与继承的关系
4.通配符


1.在集合中不使用泛型
public void test1(){
    List list = new ArrayList();
    list.add(89);
    list.add(87);
    list.add(67);
    //1.没有使用泛型,任何Object及其子类的对象都可以添加进来
    list.add(new String("AA"));
    
    for(int i = 0;i < list.size();i++){
        //2.强转为int型时,可能报ClassCastException的异常
        int score = (Integer)list.get(i);
        System.out.println(score);
    }
}
2.在集合中使用了泛型
public void test2(){
    List<Integer> list = new ArrayList<Integer>();
    list.add(78);
    list.add(87);
//        list.add("AA");
    
//        for(int i = 0;i < list.size();i++){
//            int score = list.get(i);
//            System.out.println(score);
//        }
    Iterator<Integer> it = list.iterator();
    while(it.hasNext()){
        System.out.println(it.next());
    }
}

public void test3(){
    Map<String,Integer> map = new HashMap<>();
    map.put("AA", 78);
    map.put("BB", 87);
    map.put("DD", 98);
    
    Set<Map.Entry<String,Integer>> set = map.entrySet();
    for(Map.Entry<String,Integer> o : set){
        System.out.println(o.getKey() + "--->" + o.getValue());
    }
}

3.自定义泛型类:应用
public class DAO<T> {
    public void add(T t){
        //....
    }
    public T get(int index){
        return null;
    }
    public List<T> getForList(int index){
        return null;
    }
    public void delete(int index){
        
    }
}

public class CustomerDAO extends DAO<Customer>{

}

public class TestCustomerDAO {
    public static void main(String[] args) {
        CustomerDAO c = new CustomerDAO();
        c.add(new Customer());
        c.get(0);
    }
}
【注意点】
1.对象实例化时不指定泛型,默认为:Object。
2.泛型不同的引用不能相互赋值。
3.加入集合中的对象类型必须与指定的泛型类型一致。
4.静态方法中不能使用类的泛型。
5.如果泛型类是一个接口或抽象类,则不可创建泛型  
  类的对象。
6.不能在catch中使用泛型
7.从泛型类派生子类,泛型类型需具体化


4.泛型与继承的关系
A类是B类的子类,G是带泛型声明的类或接口。那么G<A>不是G<B>的子类!

5.通配符:?
A类是B类的子类,G是带泛型声明的类或接口。则G<?> 是G<A>、G<B>的父类!
①以List<?>为例,能读取其中的数据。因为不管存储的是什么类型的元素,其一定是Object类的或其子类的。
①以List<?>为例,不可以向其中写入数据。因为没有指明可以存放到其中的元素的类型!唯一例外的是:null

6*.  List<? extends A> :可以将List<A>的对象或List<B>的对象赋给List<? extends A>。其中B 是A的子类
       ? super A:可以将List<A>的对象或List<B>的对象赋给List<? extends A>。其中B 是A的父类

9 枚举类和注解

一、枚举类
1.如何自定义枚举类。 枚举类:类的对象是有限个的,确定的。
   1.1 私有化类的构造器,保证不能在类的外部创建其对象 
   1.2 在类的内部创建枚举类的实例。声明为:public static final 
   1.3 若类有属性,那么属性声明为:private final 。此属性在构造器中赋值。
2.使用enum关键字定义枚举类
    >2.1其中常用的方法:values()  valueOf(String name);
    >2.2枚举类如何实现接口  :①让类实现此接口,类的对象共享同一套接口的抽象方法的实现。
                         ①让类的每一个对象都去实现接口的抽象方法,进而通过类的对象调用被重写的抽象方法时,执行的效果不同

public class TestSeason1 {
    public static void main(String[] args) {
        Season1 spring = Season1.SPRING;
        System.out.println(spring);
        spring.show();
        System.out.println(spring.getSeasonName());
        
        System.out.println();
        //1.values()
        Season1[] seasons = Season1.values();
        for(int i = 0;i < seasons.length;i++){
            System.out.println(seasons[i]);
        }
        //2.valueOf(String name):要求传入的形参name是枚举类对象的名字。
        //否则,报java.lang.IllegalArgumentException异常
        String str = "WINTER";
        Season1 sea = Season1.valueOf(str);
        System.out.println(sea);
        System.out.println();
        
        Thread.State[] states = Thread.State.values();
        for(int i = 0;i < states.length;i++){
            System.out.println(states[i]);
        }
        sea.show();
        
    }
}
interface Info{
    void show();
}
//枚举类
enum Season1 implements Info{
    SPRING("spring", "春暖花开"){
        public void show(){
            System.out.println("春天在哪里?");
        }
    },
    SUMMER("summer", "夏日炎炎"){
        public void show(){
            System.out.println("生如夏花");
        }
    },
    AUTUMN("autumn", "秋高气爽"){
        public void show(){
            System.out.println("秋天是用来分手的季节");
        }
    },
    WINTER("winter", "白雪皑皑"){
        public void show(){
            System.out.println("冬天里的一把火");
        }
    };
    
    private final String seasonName;
    private final String seasonDesc;
    
    private Season1(String seasonName,String seasonDesc){
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }
    public String getSeasonName() {
        return seasonName;
    }
    public String getSeasonDesc() {
        return seasonDesc;
    }
    
    @Override
    public String toString() {
        return "Season [seasonName=" + seasonName + ", seasonDesc="
                + seasonDesc + "]";
    }
//    public void show(){
//        System.out.println("这是一个季节");
//    }
}


二、注解Annotation
1.JDK提供的常用的三个注解

@Override: 限定重写父类方法, 该注释只能用于方法
@Deprecated: 用于表示某个程序元素(类, 方法等)已过时
@SuppressWarnings: 抑制编译器警告

2.如何自定义注解
以SuppressWarnings为例进行创建即可

3.元注解:可以对已有的注解进行解释说明。
Retention: SOURCE   CLASS  RUNTIME
Target:
Documented:javadoc
Inherited

10 IO流

1.java.io包下
File类:java程序中的此类的一个对象,就对应着硬盘中的一个文件或网络中的一个资源。
File file1 = new File("d:\\io\\helloworld.txt");
File file2 = new File("d:\\io\\io1");
>1.File既可以表示一个文件(.doc  .xls   .mp3  .avi   .jpg  .dat),也可以表示一个文件目录!
>2.File类的对象是与平台无关的。
>3.File类针对于文件或文件目录,只能进行新建、删除、重命名、上层目录等等的操作。如果涉及到访问文件的内容,File
是无能为力的,只能使用IO流下提供的相应的输入输出流来实现。
>4.常把File类的对象作为形参传递给相应的输入输出流的构造器中!


2.IO 流的结构


3.IO流的划分
  1) 按照流的流向的不同:输入流   输出流  (站位于程序的角度)
  2) 按照流中的数据单位的不同:字节流   字符流  (纯文本文件使用字符流 ,除此之外使用字节流)
  3) 按照流的角色的不同:节点流   处理流   (流直接作用于文件上是节点流(4个),除此之外都是处理流)

4.重点掌握
 * 抽象基类            节点流(文件流)                                        缓冲流(处理流的一种,可以提升文件操作的效率)
 * InputStream        FileInputStream (int read(byte[] b))        BufferedInputStream  (int read(byte[] b))
 * OutputStream        FileOutputStream (void write(b,0,len))        BufferedOutputStream  (flush())  (void write(b,0,len))
 * Reader                    FileReader (int read(char[] c))                BufferedReader  (readLine())  (int read(char[] c))或String readLine()
 * Writer                FileWriter (void write(c,0,len))                BufferedWriter  (flush()) (void write(c,0,len)或void write(String str))

注: 1.从硬盘中读入一个文件,要求此文件一定得存在。若不存在,报FileNotFoundException的异常
       2.从程序中输出一个文件到硬盘,此文件可以不存在。若不存在,就创建一个实现输出。若存在,则将已存在的文件覆盖
       3.真正开发时,就使用缓冲流来代替节点流
       4.主要最后要关闭相应的流。先关闭输出流,再关闭输入流。将此操作放入finally

5.其它的流
  1.转换流:实现字节流与字符流之间的转换

     InputStreamReader:输入时,实现字节流到字符流的转换,提高操作的效率(前提是,数据是文本文件)   ===>解码:字节数组--->字符串
     OutputStreamWriter:输出时,实现字符流到字节流的转换。 ===>编码:  字符串---->字节数组
   例子:从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续进行输入操作,直至当输入“e”或者“exit”时,退出程序。

  2.标准的输入输出流
    System.in: The "standard" input stream:从键盘输入数据
    System.out:The "standard" output stream:从显示器输出数据

   3.打印流 (都是输出流)  PrintStream(处理字节)  PrintWriter(处理字符) 
    可以使用System.setOut(PrintStream p)重新设置一下输出的位置。  
    PrintStream p = new PrintStream(new FileOutputStream("hello.txt"),true);
   4.数据流(处理基本数据类型、String类、字节数组)
    DataInputStream  DataOutputStream
   5.对象流(用来处理对象的)
     >对象的序列化机制:允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,
        或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象
     ObjectInputStream(Object readObject();)   ObjectOutputStream  (void writeObject(Object obj))
     如何创建流的对象:ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("person.txt")));
                  ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("person.txt")));

            
     实现序列化机制的对象对应的类的要求:①要求类要实现Serializable接口②同样要求类的所有属性也必须实现Serializable接口
                                       ③ 要求给类提供一个序列版本号:private static final long serialVersionUID;
                                   ④属性声明为static 或transient的,不可以实现序列化

   6.随机存取文件流:RandomAccessFile
      6.1既可以充当一个输入流,又可以充当一个输出流:public RandomAccessFile(File file, String mode) 
      6.2支持从文件的开头读取、写入。若输出的文件不存在,直接创建。若存在,则是对原有文件内容的覆盖。
      6.3 支持任意位置的“插入”。

11 多线程

1.理解程序、进程、线程的概念
程序可以理解为静态的代码
进程可以理解为执行中的程序。
线程可以理解为进程的进一步细分,程序的一条执行路径

2.如何创建java程序的线程(重点)
方式一:继承于Thread类
class PrintNum extends Thread{
    public void run(){
        //子线程执行的代码
        for(int i = 1;i <= 100;i++){
            if(i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
    }
    public PrintNum(String name){
        super(name);
    }
}


public class TestThread {
    public static void main(String[] args) {
        PrintNum p1 = new PrintNum("线程1");
        PrintNum p2 = new PrintNum("线程2");
        p1.setPriority(Thread.MAX_PRIORITY);//10
        p2.setPriority(Thread.MIN_PRIORITY);//1
        p1.start();
        p2.start();
    }
}
方式二:实现Runnable接口
class SubThread implements Runnable{
    public void run(){
        //子线程执行的代码
        for(int i = 1;i <= 100;i++){
            if(i % 2 == 0){
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }            
    }
}
public class TestThread{
    public static void main(String[] args){
        SubThread s = new SubThread();
        Thread t1 = new Thread(s);
        Thread t2 = new Thread(s);
        
        t1.setName("线程1");
        t2.setName("线程2");
        
        t1.start();
        t2.start();
    }
}
两种方式的对比:联系:class Thread implements Runnable
             比较哪个好?实现的方式较好。①解决了单继承的局限性。②如果多个线程有共享数据的话,建议使用实现方式,同时,共享
            数据所在的类可以作为Runnable接口的实现类。
            
            
线程里的常用方法:start()   run()  currentThread()  getName()  setName(String name) yield() join()  sleep() isAlive() 
                 getPriority()  setPriority(int i); wait()  notify() notifyAll()

3.线程的生命周期


4.线程的同步机制(重点、难点)
前提:如果我们创建的多个线程,存在着共享数据,那么就有可能出现线程的安全问题:当其中一个线程操作共享数据时,还未操作完成,
          另外的线程就参与进来,导致对共享数据的操作出现问题。
解决方式:要求一个线程操作共享数据时,只有当其完成操作完成共享数据,其它线程才有机会执行共享数据。
方式一同步代码块:
        synchronized(同步监视器){
            //操作共享数据的代码
        }
    注:1.同步监视器:俗称锁,任何一个类的对象都可以才充当锁。要想保证线程的安全,必须要求所有的线程共用同一把锁!
          2.使用实现Runnable接口的方式创建多线程的话,同步代码块中的锁,可以考虑是this。如果使用继承Thread类的方式,慎用this!
          3.共享数据:多个线程需要共同操作的变量。   明确哪部分是操作共享数据的代码。

方式二:同步方法:将操作共享数据的方法声明为synchronized。
        比如:public synchronized void show(){ //操作共享数据的代码}
    注:1.对于非静态的方法而言,使用同步的话,默认锁为:this。如果使用在继承的方式实现多线程的话,慎用!
          2.对于静态的方法,如果使用同步,默认的锁为:当前类本身。以单例的懒汉式为例。 Class clazz = Singleton.class
        
总结:释放锁:wait();
    不释放锁: sleep()   yield()  suspend() (过时,可能导致死锁)

死锁:不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁
死锁是我们在使用同步时,需要避免的问题!


5.线程的通信:如下的三个方法必须使用在同步代码块或同步方法中!
wait():当在同步中,执行到此方法,则此线程“等待”,直至其他线程执行notify()的方法,将其唤醒,唤醒后继续其wait()后的代码
notify()/notifyAll():在同步中,执行到此方法,则唤醒其他的某一个或所有的被wait的线程。
>例题:1.两个线程交替打印1-100自然数   2.生产者、消费者的例子
 

12 常用类

1. String类:不可变的字符序列(如:String str = "atguigu"; str += "javaEE")
    1.关注于String常用的方法!
    2.String类与基本数据类型、包装类;与字符数组、字节数组;
     * 1.字符串 与基本数据类型、包装类之间转换
     * ①字符串 --->基本数据类型、包装类:调用相应的包装类的parseXxx(String str);
     * ①基本数据类型、包装类--->字符串:调用字符串的重载的valueOf()方法
     * 
     * 2.字符串与字节数组间的转换
     * ①字符串---->字节数组:调用字符串的getBytes()
     * ②字节数组---->字符串:调用字符串的构造器
     * 
     * 3.字符串与字符数组间的转换
     * ①字符串---->字符数组:调用字符串的toCharArray();
     * ②字符数组---->字符串:调用字符串的构造器
       4.String与StringBuffer的转换
       ①String --->StringBuffer:使用StringBuffer的构造器:new StringBuffer(String str);
       ②StringBuffer----->String:使用StringBuffer的toString()方法    
    
   StringBuffer类:可变的字符序列
   StringBuilder类:可变的字符序列,jdk5.0新加入的,效率更高,线程不安全。
    常用的方法:添加:append(...)  删除 delete(int startIndex, int endIndex)  修改:setCharAt(int n ,char ch)  查询:charAt(int index)
            插入:insert(int index, String str)  反转reverse()  长度:length()

注:String类的不可变性:

2.时间、日期类:
  2.1System类  currentTimeMillis():返回当前时间的long型值。此long值是从1970年1月1日0点0分00秒开始到当前的毫秒数。
      此方法常用来计算时间差。
   2.2 Date类:java.util.Date
    1.  Date  d = new Date();//返回当前时间的Date:Mon May 12 15:17:01 CST 2014
             Date d1 = new Date(15231512541241L);//返回形参处此long型值对应的日期
     //getTime():返回当前日期对应的long型值。 toString()
   2.3SimpleDateFormat:java.text.SimpleDateFormat
    格式化 :日期--->文本 使用SimpleDateFormat的format()方法    
    解析:文本--->日期 使用SimpleDateFormat的parse()方法
        //1.格式化1
        SimpleDateFormat sdf = new SimpleDateFormat();
        String date = sdf.format(new Date());
        System.out.println(date);//14-5-12 下午3:24
        //2.格式化2
        SimpleDateFormat sdf1 = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
        date = sdf1.format(new Date());
        System.out.println(date);//星期一, 12 五月 2014 15:29:16 +0800
        
        //3.解析:
        Date date1 = sdf.parse("14-5-12 下午3:24");
        System.out.println(date1);
        
        date1 = sdf1.parse("星期一, 12 五月 2014 15:29:16 +0800");
//        date1 = sdf1.parse("14-5-12 下午3:24");
        System.out.println(date1);
   2.4 Calendar:日历类
         2.4.1获取实例:Calendar c = Calendar.getInstance();
         2.4.2 get()/set()/add()/date getTime()/setTime()

3.Math类

4.BigInteger  BigDecimal类

13 反射机制

1.如何创建Class的实例(重点)
       1.1过程:源文件经过编译(javac.exe)以后,得到一个或多个.class文件。.class文件经过运行(java.exe)这步,
    就需要进行类的加载(通过JVM的类的加载器),记载到内存中的缓存。每一个放入缓存中的.class文件就是一个Class的实例!
    1.2 Class的一个对象,对应着一个运行时类。相当于一个运行时类本身充当了Class的一个实例。
    1.3 java.lang.Class是反射的源头。  接下来涉及到反射的类都在java.lang.reflect子包下。如:Field  Method Constructor  Type Package..
        当通过Class的实例调用getMethods() --->Method , getConstructors() ---->Constructor
        1.4实例化Class的方法(三种):
        // 1.调用运行时类的.class属性
        Class clazz1 = Person.class;
        System.out.println(clazz1);

        Class clazz2 = Creator.class;
        System.out.println(clazz2);
        // 2.通过运行时类的对象,调用其getClass()方法
        Person p = new Person();
        Class clazz3 = p.getClass();
        System.out.println(clazz3);
        // 3.调用Class的静态方法forName(String className)。此方法报ClassNotFoundException
        String className = "com.atguigu.java.Person";
        Class clazz4 = Class.forName(className);
        System.out.println(clazz4);

2.有了Class实例以后,可以做什么?应用一:可以创建对应的运行时类的对象(重点)
    //获取运行时类的对象:方法一
    @Test
    public void test1() throws Exception{
        Class clazz = Class.forName("com.atguigu.review.Animal");
        Object obj = clazz.newInstance();
        Animal a = (Animal)obj;
        System.out.println(a);
    }
    //调用指定的构造器创建运行时类的对象
    @Test
    public void test2() throws Exception{
        Class clazz = Animal.class;
        Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);
        cons.setAccessible(true);
        Animal a = (Animal)cons.newInstance("Tom",10);
        System.out.println(a);
    }

3.有了Class实例以后,可以做什么?应用二:获取对应的运行时类的完整的类的结构:属性、方法、构造器、包、父类、接口、泛型、注解、异常、内部类。。。
如:Method[] m1 = clazz.getMethods() :获取到对应的运行时类中声明的权限为public的方法(包含其父类中的声明的public)
      Method[] m2 = clazz.getDeclaredMethods():获取到对应的运行时类中声明的所有的方法(①任何权限修饰符修饰的都能获取②不含父类中的)

4.有了Class实例以后,可以做什么?应用三:调用对应的运行时类中指定的结构(某个指定的属性、方法、构造器)(重点)
//调用指定属性
@Test
public void test3() throws Exception{
    Class clazz = Class.forName("com.atguigu.review.Animal");
    Object obj = clazz.newInstance();
    Animal a = (Animal)obj;
    //调用非public的属性
    Field f1 = clazz.getDeclaredField("name");
    f1.setAccessible(true);
    f1.set(a, "Jerry");
    //调用public的属性
    Field f2 = clazz.getField("age");
    f2.set(a, 9);
    System.out.println(f2.get(a));
    System.out.println(a);
    //调用static的属性
    Field f3 = clazz.getDeclaredField("desc");
    System.out.println(f3.get(null));
}

//调用指定的方法
@Test
public void test4() throws Exception{
    Class clazz = Class.forName("com.atguigu.review.Animal");
    Object obj = clazz.newInstance();
    Animal a = (Animal)obj;
    
    //调用非public的方法
    Method m1 = clazz.getDeclaredMethod("getAge");
    m1.setAccessible(true);
    int age = (Integer)m1.invoke(a);
    System.out.println(age);
    //调用public的方法
    Method m2 = clazz.getMethod("show", String.class);
    Object returnVal = m2.invoke(a,"金毛");
    System.out.println(returnVal);
    //调用static的方法
    Method m3 = clazz.getDeclaredMethod("info");
    m3.setAccessible(true);
//        m3.invoke(Animal.class);
    m3.invoke(null);
    
}

5.动态代理---反射的应用。体会反射的动态性
代理设计模式的原理: 
     使用一个代理将对象包装起来, 然后用该代理对象取代原始对象. 任何对原始对象的调用都要通过代理. 代理对象决定是否以及何时
将方法调用转到原始对象上

静态代理:要求被代理类和代理类同时实现相应的一套接口;通过代理类的对象调用重写接口的方法时,实际上执行的是被代理类的同样的
方法的调用。

动态代理:在程序运行时,根据被代理类及其实现的接口,动态的创建一个代理类。当调用代理类的实现的抽象方法时,就发起对被代理类同样
方法的调用。
涉及到的技术点:①提供一个实现了InvocationHandler接口实现类,并重写其invoke()方法
              ②Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),h);
            //注:obj:被代理类对象 ; h:实现了InvocationHandler接口的实现类的对象

例子见:day19-com.atguigu.java1.TestProxy.java例子

动态代理与AOP
 

14 网络编程

1.要想实现网络传输,需要考虑的问题有哪些?
   1.1 如何才能准确的定位网络上的一台主机?
   1.2 如何才能进行可靠的、高效的数据传输?


2.java如何实现的网络通信
   2.1使用IP地址---定位一台主机    使用端口号---定位一个应用  ===>InetAddress类

        >如何创建一个InetAddress的对象?getByName("");   比如:InetAddress inet = InetAddress.getByName("192.168.10.165");
        >如何获取本机的一个InetAddress的对象?getLocalHost()
        >域名:getHostName()     ip:getHostAddress()
        
   2.2对应有协议
       

对于传输层而言:分为TCP  UDP  (了解)


TCP的编程:  Socket  ServerSocket
例子:
1.客户端发送内容给服务端,服务端将内容打印到控制台上。

2.客户端发送内容给服务端,服务端给予反馈。

3.从客户端发送文件给服务端,服务端保存到本地。并返回“发送成功”给客户端。并关闭相应的连接。

UDP的编程: DatagramSocket   DatagramPacket

URL的编程:统一资源定位符一个URL的对象,对应着互联网上一个资源。
//我们可以通过URL的对象调用其相应的方法,将此资源读取(“下载”)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值