Java基础学习笔记5

来源:互联网 发布:windows 10更新 编辑:程序博客网 时间:2024/06/04 19:39

网络编程概述

         计算机网络:是指将地理位置不同的具有独立功能的多台计算机及其外部设备,                       通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议                       的管理和协调下,实现资源共享和信息传递的计算机系统。

         网络编程:用来实现网络互连的不同计算机上运行的程序间可以进行数据交换

网络编程三要素之IP概述

         1,每个设备在网络中的唯一标识

         2,每台网络终端在网络中都有一个独立的地址,在网络中传输数据就是使用这个       地址。

         3,ipconfig:查看本机IP192.168.12.42

         4,ping:测试连接192.168.40.62

         5,本地回路地址:127.0.0.1 255.255.255.255是广播地址

         6,IPv4:4个字节组成,4个0-255。大概42亿,30亿都在北美,亚洲4亿。2011        年初已经用尽。

       7,IPv6:8组,每组4个16进制数(四个零可以省略)

                     1a2b:0000:aaaa:0000:0000:0000:aabb:1f2f

                     1a2b::aaaa:0000:0000:0000:aabb:1f2f

                     1a2b:0000:aaaa::aabb:1f2f

                     1a2b:0000:aaaa::0000:aabb:1f2f

                     1a2b:0000:aaaa:0000::aabb:1f2f

网络编程三要素之端口号概述

         1,每个程序在设备上的唯一标识

         2,每个网络程序都需要绑定一个端口号,传输数据的时候除了确定发到哪台机器       上,还要明确发到哪个程序。

         3,端口号范围从0-65535

         4,编写网络应用就需要绑定一个端口号,尽量使用1024以上的,1024以下的基         本上都被系统程序占用了。

         常用端口

              mysql: 3306,oracle: 1521,web: 80,tomcat: 8080,QQ: 4000

网络编程三要素协议

         为计算机网络中进行数据交换而建立的规则、标准或约定的集合。

         UDP:面向无连接,数据不安全,速度快。不区分客户端与服务端。

         TCP

         面向连接(三次握手),数据安全,速度略低。分为客户端和服务端。

              三次握手: 客户端先向服务端发起请求, 服务端响应请求, 传输数据

Socket通信原理

         Socket套接字概述:

              1,网络上具有唯一标识的IP地址和端口号组合在一起才能构成唯一能识别的                        标识符套接字。

              2,通信的两端都有Socket。

              3,网络通信其实就是Socket间的通信。

              4,数据在两个Socket间通过IO流传输。

              5,Socket在应用程序中创建,通过一种绑定机制与驱动程序建立关系,告诉                自己所对应的IP和port。

UDP传输

         1.发送Send

              创建DatagramSocket, 随机端口号

              创建DatagramPacket, 指定数据, 长度, 地址, 端口

              使用DatagramSocket发送DatagramPacket

              关闭DatagramSocket

         2.接收Receive

              创建DatagramSocket, 指定端口号

              创建DatagramPacket, 指定数组, 长度

              使用DatagramSocket接收DatagramPacket

              关闭DatagramSocket

              从DatagramPacket中获取数据

         3.接收方获取ip和端口号

              String ip =packet.getAddress().getHostAddress();

              int port = packet.getPort();

发送端:

public class Demo_send {

       public static void main(String[] args)

                     throws Exception {

              Stringstr = "what are you doing?";

              //创建socket,相当于创建码头

              DatagramSocketsocket =new DatagramSocket();

              //创建packet,相当于集装箱

              DatagramPacketpacket =new DatagramPacket(str.getBytes(),str.getBytes().length,

InetAddress.getByName("127.0.0.1"),6666);

              //将数据进行发送

              socket.send(packet);

              //关闭码头

              socket.close();

       }

}

 

接收端:

public class Demo_receive {

       public static void main(String[] args)

              throws Exception {

              //创建socket,相当于创建码头

              DatagramSocketsocket =new DatagramSocket(6666);

              //创建packet,相当于集装箱

              DatagramPacketpacket =

                     new DatagramPacket(newbyte[1024], 1024);

              //接收数据

              socket.receive(packet);

              byte[]arr = packet.getData();

              //获取有效的字节个数

              intlen = packet.getLength();

              System.out.println(new String(arr,0,len));

              socket.close();

       }

}

UDP传输优化

       发送端:

       public class Demo_send {

       public static void main(String[] args) throws                          Exception{

              //创建socket相当于创建码头

              DatagramSocketsocket =new DatagramSocket();

              Scannersc =new Scanner(System.in);

              while(true) {

                     Stringstr =sc.nextLine();

                     if("quit".equals(str))

                            break;

                     //创建packet相当于创建集装箱

                     DatagramPacketpacket =new DatagramPacket(str.getBytes(),str.getBytes().length, InetAddress.getByName("127.0.0.1"), 6666);

                     //发货

                     socket.send(packet);

              }

              socket.close();   }

}

接收端:

public class Demo_receive {

       public static void main(String[] args)

              throws Exception {

              //创建socket相当于创建码头

              DatagramSocketsocket =new DatagramSocket(6666);

              //创建packet相当于创建集装箱

              DatagramPacketpacket =new

                     DatagramPacket(newbyte[1024], 1024);

              while(true) {

                     //接收货物

                     socket.receive(packet); 

                     byte[]arr = packet.getData();

                     intlen = packet.getLength();

                     Stringip =packet.getAddress().getHostAddress();

                     System.out.println(ip +":" + new String(arr,0,len));

              }

       }

}

UDP传输多线程

       public class Demo3_MoreThread{

       public static void main(String[] args) {

              new Receive().start();

              new Send().start();

       }

}

class Receiveextends Thread {

       public void run() {

              try {

                     //创建socket相当于创建码头

                     DatagramSocketsocket =new                                                                        DatagramSocket(6666);

                     //创建packet相当于创建集装箱

                     DatagramPacketpacket =new DatagramPacket(

                                   newbyte[1024], 1024);

                     while(true) {

                            //接收货物

                            socket.receive(packet); 

                            byte[]arr = packet.getData();

                            intlen = packet.getLength();

                            Stringip =packet.getAddress().

                                          getH      ostAddress();

                            System.out.println(ip +":"

                                   +new String(arr,0,len));

                     }

              }catch (IOExceptione) {

                     e.printStackTrace();

              }

       }

}

class Send extends Thread {

       public void run() {

              try {

                     //创建socket相当于创建码头

                     DatagramSocketsocket =new DatagramSocket();

                     Scannersc =new Scanner(System.in);

                     while(true) {

                            Stringstr =sc.nextLine();

                            if("quit".equals(str))

                                   break;

                            //创建packet相当于创建集装箱

                            DatagramPacketpacket =new                                                                DatagramPacket(str.getBytes(),

                                   str.getBytes().length,                                                                   InetAddress.getByName("127.0.0.1"),6666);

                            //发货

                            socket.send(packet);

                     }

                     socket.close();

              }  catch (IOExceptione) {

                     e.printStackTrace();

              }

       }

}

TCP协议

         1.客户端

              a,创建Socket连接服务端(指定ip地址,端口号)通过ip地址找对应的服务              器

              b,调用Socket的getInputStream()和getOutputStream()方法获取和                    服务端相连的IO流

              c,输入流可以读取服务端输出流写出的数据

              d,输出流可以写出数据到服务端的输入流

         2.服务端

              a,创建ServerSocket(需要指定端口号)

              b,调用ServerSocket的accept()方法接收一个客户端请求,得到一个                        Socket

              c,调用Socket的getInputStream()和getOutputStream()方法获取和              客户端相连的IO流

              d,输入流可以读取客户端输出流写出的数据

              e,输出流可以写出数据到客户端的输入流

       服务器端:

       public class Demo2_Server {

 

       public static void main(String[] args)

                     throws IOException {

              ServerSocketserver =new ServerSocket(12345);

              // 接收客户端的请求

              Socketsocket = server.accept();

              // 获取客户端输入流

              InputStreamis = socket.getInputStream();

              // 获取客户端输出流

              OutputStreamos =socket.getOutputStream();

              // 服务器向客户端写出数据

              os.write("百度一下你就知道".getBytes());

 

              byte[]arr = newbyte[1024];

              // 读取客户端发过来的数据

              intlen = is.read(arr);

              // 将数据转换为字符串进行打印

              System.out.println(new String(arr, 0,len));

              socket.close();

       }

 

}

 

       客户端:

       public class Demo1_Client {

 

       public static void main(String[] args)

                     throws Exception {

              //创建Socket链接服务器

              Socketsocket = new Socket("127.0.0.1",12345);

              //获取客户端输入流

              InputStreamis = socket.getInputStream();

              //获取客户端输出流

              OutputStreamos =socket.getOutputStream();

             

              byte[]arr = newbyte[1024];

              //读取服务器发过来的数据

              intlen = is.read(arr);

              //将数据转换为字符串进行打印

              System.out.println(new String(arr,0,len));

             

              //客户端向服务写数据

              os.write("学习IT技术好么?".getBytes());

              socket.close();

       }

}

 

TCP协议代码优化

       服务器端:

public class Demo2_Server {

 

       public static void main(String[] args)

                     throws IOException {

              //创建服务器

              ServerSocketserver =new ServerSocket(9999);

              //接受客户端的请求

              Socketsocket = server.accept();

              //获取输入输出流

              InputStreamis = socket.getInputStream();

              OutputStreamos =socket.getOutputStream();

              //将字节流包装成了字符流

              BufferedReaderbr =new BufferedReader(

                     new InputStreamReader(is));

              //PrintStream有写出换行的方法(/r/n为结束标志)

              PrintStreamps = new PrintStream(os);

             

              ps.println("欢迎咨询百度文库");

              System.out.println(br.readLine());

              ps.println("请提供注册信息");

              System.out.println(br.readLine());

              server.close();

              socket.close();

       }

}

       客户端:

       public class Demo2_Client {

 

       public static void main(String[] args)

                     throws IOException {

              //创建Socket指定ip地址和端口号

              Socketsocket = new Socket("127.0.0.1", 9999);

              //获取输入输出流

              InputStreamis = socket.getInputStream();

              OutputStreamos =socket.getOutputStream();

              //将字节流包装成了字符流

              BufferedReaderbr =new BufferedReader(

                            new InputStreamReader(is));

              //PrintStream有写出换行的方法

              PrintStreamps = new PrintStream(os);

             

              System.out.println(br.readLine());

              ps.println("我想注册");

              System.out.println(br.readLine());

              ps.println("好的");

              socket.close();  

       }

}

服务端是多线程的

       //创建服务器

              ServerSocketserver =new ServerSocket(9999);

              while(true) {

                     //接受客户端的请求

                     final Socketsocket = server.accept();

                     new Thread() {

                            publicvoid run() {

                                   try {

                                   BufferedReaderbr =new                                                                  BufferedReader(new InputStreamReader

                                   (socket.getInputStream()));

                                   PrintStreamps =new PrintStream(

                                   socket.getOutputStream());

                                          ps.println("欢迎咨询传智播客");

                                          System.out.println(br.readLine());

                                          ps.println("报满了,请报下一期吧");

                                          System.out.println(br.readLine());

                                          socket.close();

                                   }catch (IOExceptione) {

                                          e.printStackTrace();

                                   }

                            }

                     }.start();

              }

类的加载概述和加载时机

         类的加载概述

              1,当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加                       载,连接,初始化三步来实现对这个类进行初始化。

              2,加载:就是指将class文件读入内存,并为之创建一个Class对象。任何                     类被使用时系统都会建立一个Class对象。

              3,连接

                     验证 是否有正确的内部结构,并和其他类协调一致

                     准备 负责为类的静态成员分配内存,并设置默认初始化值

                     解析 将类的二进制数据中的符号引用替换为直接引用

              4,初始化 基本的初始化步骤

         加载时机

              1,创建类的实例

              2,访问类的静态变量,或者为静态变量赋值

              3,调用类的静态方法

              4,使用反射方式来强制创建某个类或接口对应的java.lang.Class对象

              5,初始化某个类的子类

              6,直接使用java.exe命令来运行某个主类

类加载器的概述

         负责将.class文件加载到内存中,并为之生成对应的Class对象。虽然我们不需             要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行。

         类加载器的分类

              BootstrapClassLoader 根类加载器

              ExtensionClassLoader 扩展类加载器

              Sysetm ClassLoader系统类加载器

         类加载器的作用

              BootstrapClassLoader 根类加载器

                     也被称为引导类加载器,负责Java核心类的加载

                     比如System,String等。在JDK中JRE的lib目录下rt.jar文件中

              ExtensionClassLoader 扩展类加载器

                     负责JRE的扩展目录中jar包的加载。

                     在JDK中JRE的lib目录下ext目录

              Sysetm ClassLoader系统类加载器

                     负责在JVM启动时加载来自java命令的class文件,以及classpath环                         境变量所指定的jar包和类路径

反射概述

         反射概述

              1,JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所              有属性和方法;

              2,对于任意一个对象,都能够调用它的任意一个方法和属性;

              3,动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制

              4,要想解剖一个类,必须先要获取到该类的字节码文件对象。

              5,而解剖使用的就是Class类中的方法,所以先要获取到每一个字节码文件                         对应的Class类型的对象。

 

         三种方式

              a:Object类的getClass()方法,判断两个对象是否是同一个字节码文件

              b:静态属性class,锁对象

              c:Class类中静态方法forName(),读取配置文件

       获取class文件对象的三种方式

              //Class类中静态方法forName(),读取配置文件

              Classclazz1 = Class.forName("com.test.reflect.Person");

              //静态属性class,锁对象

              Classclazz2 = Person.class;

              //Object类的getClass()方法,判断两个对象是否是同一个字节码文件

              Personp = new Person();

              Classclazz3 =p.getClass();

             

              System.out.println(clazz1==clazz2);

              System.out.println(clazz2==clazz3);

Class.forName()读取配置文件举例

       public class Demo2_Reflect {

 

       public static void main(String[] args)

               throws Exception{      

              //创建输入流对象,关联配置文件

              //(配置文件中就是类的包名:com.test.reflect.Apple)

              BufferedReaderbr =new BufferedReader(new                     FileReader("config1.properties"));

              //读取配置文件一行内容,获取该类的字节码对象

              Class<?>clazz = Class.forName(br.readLine());

              //通过字节码对象创建实例对象

              Fruitf = (Fruit)clazz.newInstance();

              Juicerj = new Juicer();

              j.run(f);

       }

}

interface Fruit {

       public void squeeze();

}

 

class Apple implements Fruit {

       public void squeeze() {

              System.out.println("榨出一杯苹果汁儿");

       }

}

 

class Orange implements Fruit {

       public void squeeze() {

              System.out.println("榨出一杯桔子汁儿");

       }

}

 

class Juicer {

       public void run(Fruit f) {

              f.squeeze();

       }

}

通过反射获取带参构造方法并使用

         Constructor:Class类的newInstance()方法是使用该类无参的构造函数创  建对象, 如果一个类没有无参构造函数, 就不能这样创建了,可以调用Class类     的getConstructor(String.class,int.class)方法获取一个指定的构造     函数然后再调用Constructor类的newInstance("张三",20)方法创建对象

       public classDemo3_Constructor {

 

       public static void main(String[] args)

              throws Exception {

              Classclazz = Class.forName(

                            "com.test.reflect.Person");

              // 调用类的空参构造创建对象

              // Person p = (Person)clazz.newInstance();

              // 获取所有的构造

              // Constructor[] cs =clazz.getConstructors();

              // 获取构造的参数

              // Class[] ss = cs[0].getParameterTypes();

              // 获取有参构造

              Constructorc =clazz.getConstructor

                            (String.class,int.class);

              // 通过有参构造创建对象

              Personp = (Person)c.newInstance("张三", 23);

              System.out.println(p);

       }

}

通过反射获取成员变量并使用

         Field:Class.getField(String)方法可以获取类中的指定字段(可见的),       如果是私有的可以用getDeclaedField("name")方法获取,通过set(obj, "      李四")方法可以设置指定对象上该字段的值, 如果是私有的需要先调用      setAccessible(true)设置访问权限,用获取的指定的字段调用get(obj)可 以获取指定对象中该字段的值

       public class Demo4_Field {

 

       public static void main(String[] args)

              throws Exception {

              Classclazz = Class.forName

                            ("com.test.reflect.Person");

              Constructorc =clazz.getConstructor

                     (String.class,int.class);

              Personp = (Person)c.newInstance("王五",25);

              //获取姓名字段(非私有字段)

              //Field f =clazz.getField("name");

              //修改姓名的值

              //f.set(p, "李四");

              //暴力反射获取私有字段

              Fieldf = clazz.getDeclaredField("name");

              //去除私有权限

              f.setAccessible(true);

              //修改值

              f.set(p,"李四");

              System.out.println(p);

       }

}

通过反射获取方法并使用

         Method:Class.getMethod(String,Class...) 和      Class.getDeclaredMethod(String, Class...)方法可以获取类中的指      定方法,调用invoke(Object,Object...)可以调用该方   法,Class.getMethod("eat")invoke(obj)          Class.getMethod("eat",int.class)invoke(obj,10)

       publicclass Demo5_Method {

 

       public static void main(String[] args)

       throws Exception {

              Classclazz = Class.forName(

                     "com.test.reflect.Person");

              Constructorc =clazz.getConstructor(

                     String.class,int.class);

              Personp = (Person)c.newInstance("李四",24);

              //获取eat方法

              Methodm = clazz.getMethod("eat");

              //调用方法

              m.invoke(p);

              //获取有参数的eat方法

              Methodm2 = clazz.getMethod("eat",int.class);

              m2.invoke(p, 3);

       }

}

通过反射越过泛型检查

         ArrayList<Integer>的一个对象,在这个集合中添加一个字符串数据,如何     实现呢?

       public class Test1 {

 

       public static void main(String[] args)

              throws Exception {

              //泛型只在编译期有效,在运行期会被擦除掉

              ArrayList<Integer>list =new ArrayList<>();

              list.add(11);

              list.add(22);

             

              //获取字节码对象

              Classclazz = Class.forName(

                     "java.util.ArrayList");

              //获取add方法

              Methodm = clazz.getMethod("add", Object.class);

              m.invoke(list,"abc");

              System.out.println(list);

       }

 

}

 

通过反射写一个通用的设置某个对象的某个属性为指定的值

       publicvoid setProperty(Object obj, String propertyName, Object value){},此方法可将obj对象中名为propertyName的属性的值设置为  value

       示例代码:

public class Tool {

       public voidsetProperty(Object obj, StringpropertyName, Object value) throws Exception {

              // 获取字节码对象

              Classclazz =obj.getClass();

              // 暴力反射获取字段

              Fieldf = clazz.getDeclaredField(propertyName);

              // 去除权限

              f.setAccessible(true);

              // 设置属性

              f.set(obj,value);

       }

}

使用方法:

public static void main(String[] args) throws Exception {

              Students = new Student("张三",23);

              System.out.println(s);

              Tooltool = new Tool();

              tool.setProperty(s,"name", "李四");

              System.out.println(s);

             

       }

动态代理的概述和实现

         动态代理概述

              1,代理:本来应该自己做的事情,请了别人来做,被请的人就是代理对象。

              2,举例:春节回家买票让人代买

              3,动态代理:在程序运行过程中产生的这个对象,而程序运行过程中产生对象               其实就是我们刚才反射讲解的内容,所以,动态代理其实就是通过反射来                       生成一个代理

              4,在Java中java.lang.reflect包下提供了一个Proxy类和一个                             InvocationHandler接口,通过使用这个类和接口就可以生成动态代理                    对象。JDK提供的代理只能针对接口做代理。我们有更强大的代理cglib,               Proxy类中的方法创建动态代理类对象

              5,public static ObjectnewProxyInstance(ClassLoader                      loader,Class<?>[]interfaces,InvocationHandler h)

              6,最终会调用InvocationHandler的方法

              7,InvocationHandlerObject invoke(Object proxy,Method                         method,Object[] args)

         使用测试类:

       public class Test {

       public static void main(String[] args) {

              UserImpui = new UserImp();

              MyInvocationHandlerm =new                                                                             MyInvocationHandler(ui);

              Useru = (User) Proxy.newProxyInstance(

                            ui.getClass().getClassLoader(),                                                  ui.getClass().getInterfaces(),m);

              u.add();

              u.delete();

       }

}

 

 

       public classMyInvocationHandler implements                      InvocationHandler {

              private Objecttarget;

       public MyInvocationHandler(Objecttarget) {

              this.target =target;

       }

 

       @Override

       public Object invoke(Objectproxy,

              Methodmethod, Object[]args) throws Throwable {

              System.out.println("权限校验");

              // 执行被代理target对象的方法

              method.invoke(target,args);

              System.out.println("日记记录");

              return null;

       }

}

 

       public class UserImp implements User{

 

       @Override

       public void add() {

              System.out.println("添加");

       }

 

       @Override

       public void delete() {

              System.out.println("删除");

       }

 

}

 

public interface User {

       public void add();

       public void delete();

 

}

 

模版(Template)设计模式概述和使用

         模版设计模式概述:模版方法模式就是定义一个算法的骨架,而将具体的算法延                       迟到子类中来实现

         优点:使用模版方法模式,在定义算法骨架的同时,可以很灵活的实现具体的                           算法,满足用户灵活多变的需求

         缺点:如果算法骨架有修改的话,则需要修改抽象类

       public class Demo1_Template {

       public static void main(String[] args) {

              Demod = new Demo();

              System.out.println(d.getTime());

       }

}

class Demo extends GetTime{

 

       @Override

       public void code() {

              inti=0;

              while(i<1000000){

                     System.out.println("x");

                     i++;

              }

       }

}

abstract class GetTime{

       //防止子类重写

       public final long getTime(){

              longstart = System.currentTimeMillis();

              code();

              longend = System.currentTimeMillis();

              returnend-start;

       }

       //让子类重写

       public abstract void code();

}

所学设计模式:装饰,单例,简单工厂,工厂方法,适配器,模版

自己实现枚举类

         枚举概述:是指将变量的值一一列出来,变量的值只限于列举出来的值的范围内。               举例:一周只有7天,一年只有12个月等。

         回想单例设计模式:单例类是一个类只有一个实例

                     那么多例类就是一个类有多个实例,但不是无限个数的实例,而是有限个                      数的实例。这才能是枚举类。

         方式一:无参构造

       public class Week1 {

       public static final Week1 MON =new Week1();

       public static final Week1 TUE =new Week1();

       public static final Week1 WED =new Week1();

       //私有构造,不让其他类创建

       private Week1(){}

}

         方式二:有参构造

public class Week2 {

public static final Week2 MON =new Week2("星期一");

public static final Week2 TUE =new Week2("星期二");

public static final Week2 WED =new Week2("星期三");

       private Stringname;

       private Week2(Stringname){

              this.name =name;

       }

       public String getName() {

              returnname;

       }

       public void setName(String name) {

              this.name =name;

       }

}

 

         方式三:抽象类

       publicabstract class Week3 {

       public static final Week3 MON =new Week3("星期一"){

              @Override

              public void show() {

                     System.out.println("星期一");

              }

       };

       public static final Week3 TUE =new Week3("星期二"){

              @Override

              public void show() {

                     System.out.println("星期二");

              }

       };

       public static final Week3 WED =new Week3("星期三"){

              @Override

              public void show() {

                     System.out.println("星期三");

              }

       };

       private Stringname;

       private Week3(Stringname){

              this.name =name;

       }

       public String getName() {

              returnname;

       }

       public abstract void show();

}

 

通过enum实现枚举类

       方式一:

       publicenum Week1 {

       MON,TUE,WED;

       }

       方式二:

       publicenum Week2 {

       MON("星期一"),TUE("星期二"),WED("星期三");

       private Stringname;

       private Week2(Stringname){

              this.name =name;

       }

       public String getName() {

              returnname;

       }

}

使用:

              Week2mon = Week2.MON;

              System.out.println(mon.getName());

       方式三:

public enum Week3 {

       MON("星期一"){

              @Override

              public void show() {

                     System.out.println("星期一");

              }

       },TUE("星期二"){

              @Override

              public void show() {

                     System.out.println("星期二");

              }

       },WED("星期三"){

              @Override

              public void show() {

                     System.out.println("星期三");

              }

       };

       private Stringname;

       private Week3(Stringname){

              this.name =name;

       }

       public String getName() {

              returnname;

       }

       public abstract void show();

}

使用:

              Week3tue = Week3.TUE;

              tue.show();

枚举的注意事项

         1,定义枚举类要用关键字enum

         2,所有枚举类都是Enum的子类

         3,枚举类的第一行上必须是枚举项,最后一个枚举项后的分号是可以省略的,但       是如果枚举类有其他的东西,这个分号就不能省略。建议不要省略

         4,枚举类可以有构造器,但必须是private的,它默认的也是private的。

         5,枚举类也可以有抽象方法,但是枚举项必须重写该方法

        6,枚举在switch语句中的使用

枚举类的常见方法

         int ordinal()获取枚举项在枚举类中的编号

         int compareTo(E o)比较编号

         String name()获取实例名称

         String toString()调用toString方法

         <T> T valueOf(Class<T> type,String name)由字节码对象获取枚举项

         values() 此方法虽然在JDK文档中查找不到,但每个枚举类都具有该方法,它             遍历枚举类的所有枚举值非常方便

         示例代码:

              Week2mon = Week2.MON;

              Week2tue = Week2.TUE;

              Week2wed = Week2.WED;

              //获取枚举项的编号

              System.out.println(mon.ordinal());

              System.out.println(tue.ordinal());

              System.out.println(wed.ordinal());

              //比较的是编号

              System.out.println(mon.compareTo(tue));

              System.out.println(mon.compareTo(wed));

              //获取实例名称

              System.out.println(mon.name());

              System.out.println(mon.toString());

              //通过字节码对象获取枚举项

              Week2mon1 = Week.valueOf(Week2.class,"MON");

              System.out.println(mon);

              //获取所有的枚举项

              Week2[]arr = Week2.values();

              for(Week2week:arr){

                     System.out.println(week.getName());

              }

JDK7的六个新特性回顾和讲解

         A:二进制字面量(0b110)

         B:数字字面量可以出现下划线(100_000)

         C:switch 语句可以用字符串

         D:泛型简化,菱形泛型

         E:异常的多个catch合并,每个异常用或|

       F:try-with-resources 语句

JDK8的新特性

         接口中可以定义有方法体的方法,如果是非静态,必须用default修饰,如果是静   态的就不用了(接口中可以定义非静态的一般方法,但必须用default修饰;也可以 有静态方法)

       class Test {

       public void run() {

              final int x = 10;

              class Inner {

                     publicvoid method() {

                            System.out.println(x);

                     }

              }

              Inneri = new Inner();

              i.method();

       }     

}

         局部内部类在访问他所在方法中的局部变量必须用final修饰,为什么?

                     因为当调用这个方法时,局部变量如果没有用final修饰,他的生命周期                  和方法的生命周期是一样的,当方法弹栈,这个局部变量也会消失,那么如              果局部内部类对象还没有马上消失想用这个局部变量,就没有了,如果用                    final修饰会在类加载的时候进入常量池,即使方法弹栈,常量池的常量                    还在,也可以继续使用

0 0