乐趣区

关于java-se:JAVASE注解反射内部类socketJDK新特性

1 注解

概述: 注解能够加强咱们的 java 代码,同时利用反射技术能够裁减实现很多性能。它们被广泛应用于三大框架底层。传统咱们通过 xml 文本文件申明形式,而当初最支流的开发都是基于注解形式,代码量少,框架能够依据注解去主动生成很多代码,从而缩小代码量,程序更易读。例如最火爆的 SpringBoot 就齐全基于注解技术实现。

分类:
1、JDK 自带注解
2、元注解
3、自定义注解

JDK 注解:
JDK 注解的注解,就 5 个:
1、@Override
2、@Deprecated 标记就表明这个办法曾经过期了,但我就要用,别提醒我过期
3、@SuppressWarnings(“deprecation”) 疏忽正告
4、@SafeVarargs jdk1.7 呈现,堆净化,不罕用
5、@FunctionallInterface jdk1.8 呈现,配合函数式编程拉姆达表达式,不罕用

元注解:
形容注解的注解,就 5 个:
1、@Target 注解用在哪里:类上、办法上、属性上

ElementType.FIELD 利用于字段或属性
ElementType.METHOD 利用于办法级
ElementType.TYPE 利用于类的元素 

2、@Retention 注解的生命周期:源文件中、class 文件中、运行中

RetentionPolicy.RUNTIME 在运行时无效 

3、@Inherited 容许子注解继承
4、@Documented 生成 javadoc 时会蕴含注解,不罕用
5、@Repeatable 注解为可反复类型注解,能够在同一个中央屡次应用,不罕用

自定义注解:

// 一,自定义注解:@interface  注解名
// 形容注解能够呈现的地位 -- 多个地位上用
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)// 形容注解的生命周期
@interface Test{
  //1,给注解增加性能 -- 属性 -- 语法非凡
  String local()default "";//3,给属性设置默认值,不便间接应用 @Test
  String value();//5, 非凡的属性 value}
// 二,应用注解:@Test
//@Test(local="class")//2,当 Test 注解增加了属性时,须要给属性赋值
class taotao{
  String name;
//  @Test//4,因为属性设置好了默认值,用时就简略了
//  @Test("123")//6, 因为 value 属性比拟非凡,能够简写,赋值时省略掉 value=
  @Test(local = "method",value="")//7, 给多个属性赋值时,不能省略 value=
  public  void show(){System.out.println("show()...");
  }
}

2 反射

概述:
Reflection(反射) 是 Java 程序开发语言的特色之一,它容许运行中的 Java 程序对本身进行查看,或者说“自审“,也有称作“自省”。反射十分弱小,它甚至能间接操作程序的公有属性。咱们后面学习都有一个概念,private 的只能类外部拜访,内部是不行的,但这个规定被反射赤裸裸的突破了。

反射就像一面镜子,它能够在运行时获取一个类的所有信息,能够获取到任何定义的信息(包含成员变量,成员办法,结构器等),并且能够操纵类的字段、办法、结构器等局部。

2.1 创建对象

Class.forName(“类的全门路”);
类名.class
对象.getClass();

测试:

// 形式 1:Class.forName("类的全门路");
        Class clazz = Class.forName("java.lang.String");
// 形式 2:类名.class
        Class clazz2 = String.class;
// 形式 3:对象.getClass();
        Class clazz3 = new String().getClass();

2.2 罕用办法


测试:

public static void main(String[] args) throws Exception {//        method();// 获取 Class 对象
//        method2();// 获取构造方法
//        method3();// 获取成员办法
//        method4();// 获取成员变量
//        method5();// 通过反射创建对象}
    public static void method5() throws Exception {
        //1,获取 Class 对象
        Class<Test2_Student> a = Test2_Student.class;
        //2,调用实例化办法 -- 也要触发构造方法,而且触发的是无参结构
        //java.lang.InstantiationException 没有无参结构报异样
        Test2_Student as = a.newInstance();
        System.out.println("as="+as);
        // 重写 toString() 前:as=day18.Test2_Student@15db9742
        // 重写 toString() 后:as=Test2_Student [name=null, age=0, score=0.0]
        // 怎么触发含参结构 -- 匹配构造方法里 参数列表
        Constructor<Test2_Student> ass = a.getConstructor(String.class);// 指定
        // X 是创建对象时间隔的参数
        Test2_Student ass2 = ass.newInstance("jack");
        System.out.println("ass2="+ass2);
        // 创立 2 个参数的构造方法
        Constructor<Test2_Student> bss = a.getConstructor(String.class,int.class,double.class);
        Test2_Student bsss = bss.newInstance("taotao",20,20.1);
        System.out.println("bsss="+bsss);
    }
    // 获取成员变量
    public static void method4() {
        //1,获取 Class 对象
        Class a = Test2_Student.class;
        //2,获取所有的成员变量 -- 只能获取到 public 润饰的变量
        Field[] as = a.getFields();
        //3, 遍历数组,失去每个变量 ass
        for(Field ass:as) {
            //4, 获取变量名
            System.out.println(ass.getName());
            //5,获取变量类型
            System.out.println(ass.getType().getName());
        }
    }
    // 获取成员办法
    public static void method3() {
        //1, 获取 Class 对象
        Class<Test2_Student> a = Test2_Student.class;
        //2,获取所有成员办法们 -- 包含本人的和父类的
        Method[] as = a.getMethods();
        //3, 遍历数组,失去每个办法 ass
        for(Method ass:as) {
            //4, 获取办法名
            System.out.println(ass.getName());
            //5,获取办法的参数的类型
            Class[] asss = ass.getParameterTypes();
            System.out.println(Arrays.toString(asss));
        }
    }
    // 获取构造方法
    public static void method2() {
        //1,获取 Class 对象 -- 封装了.class 文件里的所有数据
        Class c1 = Test2_Student.class;
        //2, 调用办法
//            -- 取得所有公开的构造方法, 并存入数组
        Constructor[] cs = c1.getConstructors();
        //3, 获取每个构造方法
        for(Constructor css:cs) {
            //4, 获取构造方法的名字
            System.out.println(css.getName());
            //5, 获取构造方法的参数
            Class[] css1=css.getParameterTypes();
            System.out.println(Arrays.toString(css1));
        }    
    }
    // 获取 Class 对象
    public static void method() throws ClassNotFoundException {//    Class.forName(“类的全门路”);
//    类名.class
//    对象.getClass();
        Class c = Class.forName("test.reflect.Test3_Reflect2");
        Class c1 = Test3_Reflect2.class;
        Class c2 = new Test3_Reflect2().getClass();
    }

2.3 暴力反射

根本 API:

    public static void main(String[] args) throws Exception {//        method();// 暴力反射成员办法们
//        method2();// 暴力反射成员变量

    public static void method2() throws Exception {
        Class<Person> a = Person.class;
        Field[] as = a.getDeclaredFields();
        for(Field ass:as) {System.out.println(ass.getName());
            System.out.println(ass.getType().getName());
        }
        // 获取指定的变量
        Field f = a.getDeclaredField("score");
        f.setAccessible(true);
        Object obj = a.newInstance();
        // 设置值 --set(1,2)-- 1 是指对象名称,2 是要设置的具体值
        f.set(obj, 20.0);
        // 获取值 --get(1)-- 1 是指对象名称
        System.out.println(f.get(obj));
    }
    public static void method() throws Exception{
        //1, 获取 Class 对象
        Class<Person> a = Person.class;
        //2, 调用办法暴力反射
        Method[] as = a.getDeclaredMethods();
        //3, 遍历数组,失去每个办法 ass
        for(Method ass:as) {
            //4, 获取办法名称
            System.out.println(ass.getName());
            //5, 获取办法的参数的类型
            Class<?>[] asss = ass.getParameterTypes();
            System.out.println(Arrays.toString(asss));    
        }
        // 暴力反射 某个办法
        //getDeclaredMethod(1,2)-- 获取指定的办法
        //-- 1 是指办法名 -- 2 是指办法须要的参数类型的 Class 对象
        Method m = a.getDeclaredMethod("game", String.class);
        Method m1 = a.getDeclaredMethod("eat");
        // 暴力反射:除了用对 API,另外还须要开启拜访权限
        m.setAccessible(true);
        // 执行办法 --invoke(1,2)-- 1 是指对象名称 -- 2 是办法须要传入的参数
        Object obj = a.newInstance();
        m1.invoke(obj, null);
//        m.invoke(obj, "张三");
    }

3 外部类

概述:
如果一个类存在的意义就是为指定的另一个类,能够把这个类放入另一个类的外部。就是把类定义在类的外部的状况就能够造成外部类的模式。
A 类中又定义了 B 类,B 类就是外部类。B 类能够当做 A 类的一个成员对待。

特点:
1、外部类能够间接拜访外部类中的成员,包含公有成员
2、外部类要拜访外部类的成员,必须要建设外部类的对象
3、在成员地位的外部类是成员外部类
4、在部分地位的外部类是部分外部类

3.1 成员外部类

// 测试 外部类
public class Test1_Inner {public static void main(String[] args) {
        // 创立外部类的对象的语法:外部类对象. 外部类对象
        Outer.Inner in = new Outer().new Inner();
        in.in();
        System.out.println(in.age);
    }
}
// 成员外部类
class Outer{// 外部类
    String name = "jack";
    public void out() {
        //3,外部类 拜访外部类的 成员 -- 不能够间接用,须要创立外部类对象
        new Inner().in();
        System.out.println("out()...");
    }
    //1,外部类 -- 能够看做是外部类的一个非凡成员,和其余成员是同级关系
    class Inner{
        int age = 20;
        public void in() {
            //2,外部类 能够间接 拜访外部类 的成员 -- 能够
            System.out.println(name);
            System.out.println("in()...");
        }
    }
}
被 private 润饰
package cn.tedu.inner;
// 测试外部类被 private 润饰
public class Test5_InnerClass2 {public static void main(String[] args) {// 创立外部类对象,并执行 show()
// Outer2.Inner2 oi = new Outer2().new Inner2();// 报错,Inner2 曾经被 private 了
//3,测试被 private 的外部类的资源是否执行!new Outer2().test();
    }
}
class Outer2{
 //2,如果想要拜访 private 的外部类,能够拜访外部类提供的对应办法
    public void test() {
        // 拜访外部类办法
        new Inner2().show();
    }
// 地位在类里办法外 -- 成员外部类
//1,外部类能够被 private 润饰,然而外界无奈间接创建对象了!private class Inner2{public void show() {System.out.println("Inner2.show()");
        }
    }
}
被 static 润饰
package cn.tedu.inner;
// 测试外部类被 static 润饰
public class Test6_InnerClass3 {public static void main(String[] args) {// 创立外部类对象测试 show()
    // Outer3.Inner3 oi = new Outer3().new Inner3();// 报错,起因是 Inner3 是动态的外部类
        Outer3.Inner3 oi = new Outer3.Inner3();//Outer3.Inner3 通过类名. 调用类中的动态资源
        oi.show();
        Outer3.Inner3.show2();// 调用动态外部类里的静态方法}
}
class Outer3{
    //1,外部类被 static 润饰 -- 随着类的加载而加载,会造成内存资源节约,并不罕用!static class Inner3{public void show() {System.out.println("Inner3.show()");
        }
        static public void show2() {System.out.println("Inner3.show2()");
        }
    }
}

3.2 匿名外部类

// 测试 匿名外部类
// 总结:// 接口能够间接 new 对象,要配合匿名外部类应用(在内部类里重写了办法
public class Test2_Inner {public static void main(String[] args) {
        // 优化计划:间接 new 接口,要配合匿名外部类应用(在内部类里重写了办法)-- 占内存少,不必实现类
        Inner in = new Inner() {
            @Override
            public void save() {System.out.println("数据保留胜利");
            }
            @Override
            public void delete(int id) {System.out.println("数据删除胜利,id 是:"+id);
            }
        };
//        }.save();// 调用指定办法
//    }.delete(5);// 留神:调用指定办法 -- 匿名对象一次只执行一个工作,只能 2 选 1
        in.save();
        in.delete(10);
    }
}
interface Inner{
    // 简写模式
    void save();
    void delete(int id);
}

4socket

4.1ServerSocket 服务器端

创建对象:

    ServerSocket(int port) 
      创立绑定到特定端口的服务器套接字。

罕用办法:

    Socket accept() 
      侦听并承受到此套接字的连贯。void close() 
      敞开此套接字。

测试:

//socket 通信的服务器端
public class Test1_Server {public static void main(String[] args) throws IOException {
        //1,开始服务器 -- 端口号 0~65535
        // 在指定的 8887 端口号处,期待客户端的连贯
        ServerSocket server = new ServerSocket(8887);
        System.out.println("服务器已开启。。。");
        
        //2,接管客户端连贯申请,并建设通信通道 Socket
        Socket accept = server.accept();
        System.out.println("接管一个客户端的申请。。");
        
        //3,读取客户端发来的数据
        InputStream in = accept.getInputStream();
        // 读到的数据默认是 int,转成字符类型
        for(int i = 0;i<5;i++) {char b = (char)in.read();
            System.out.print(b);
        }
        //4,服务器发送数据
        OutputStream out = accept.getOutputStream();
        String output = new Scanner(System.in).nextLine();
        out.write(output.getBytes());
        System.out.println("发送胜利");
        //
        
    }

}

4.2socket 客户端

创建对象:

Socket(String host, int port) 
          创立一个流套接字并将其连贯到指定主机上的指定端口号。

罕用办法:

InputStream getInputStream() 
          返回此套接字的输出流。OutputStream getOutputStream() 
          返回此套接字的输入流。

测试:

//socket 通信的客户端
public class Test2_Client {
    static Socket socket =null;

    public static void main(String[] args) throws IOException {method2();// 读取
        method();// 写出
        
        //1,连贯指定的服务器
        // 本机 ip--127.0.0.1
        // 理论工作中,要写服务器的真是 ip
        socket = new Socket("172.199.26.30",8888);
        System.out.println("客户端与服务器连贯胜利");
    }

    private static void method2() throws IOException {
        //3, 读取服务器的数据
                InputStream in = socket.getInputStream();
                for(int i = 0;i<5;i++) {char b = (char)in.read();
                    System.out.print(b);
                }
    }

    private static void method() throws IOException {
        //2,给服务器写出数据
                OutputStream out = socket.getOutputStream();
                System.out.println("请输出发给服务器的数据");
                String input = new Scanner(System.in).nextLine();
                out.write(input.getBytes());
                System.out.println("发送胜利");
                out.flush();}

}

4.3BufferedReader

// 服务器端
// 读一行:BufferedReader()--readline()
// 写一行:PrintWrite()--println()
public class Test3_BufferedReader {public static void main(String[] args) throws IOException {
        //1, 开启服务器, 凋谢端口
        ServerSocket server = new ServerSocket(8886);
        System.out.println("服务器已开启");
        //2,接管客户端申请,建设连贯通道 Socket
        Socket accept = server.accept();
        System.out.println("Sosket 通道已建设");
//        rwmethod();// 边读边写}

    public static void rwmethod() throws IOException {
        //1, 创立读取对象
        BufferedReader br = new BufferedReader(new FileReader("./a.txt"));
        PrintWriter pw = new PrintWriter(new FileWriter("./b.txt"));
        String line ="";
        while((line = br.readLine())!=null) {// 只有有数据,就始终读,没数据就返回 null    
            pw.println(line);
        }
        br.close();
        pw.close();}

/**
 * 用来写一行:PW
 * @param path 要把文档写在那个文件里去
 * @param date 写的内容
 * @throws IOException
 */
    public static void writeline(String path,String date) throws IOException {
        //1, 创建对象
        PrintWriter pw = new PrintWriter(new FileWriter(path));
        //2,写出一行数据
        pw.println(date);
        //3, 开释资源
        pw.close();}

/**
 * 用来读一行
 * @throws IOException
 */
    public static void readline(String path) throws IOException {
        // 读一行:BufferedReader
        BufferedReader br = new BufferedReader(new FileReader(path));
        // 读不到数据时,readline() 返回 null
//        String line = br.readLine();
        
        String line ="";// 创立变量,记录读取到的一行数据
        while(line !=null) {// 只有有数据,就始终读,没数据就返回 null
            line = br.readLine();// 一行一行读取数据
            System.out.println("line="+line);
        }
        br.close();}
}

4.4BufferedSocket

// 客户端
public class Test3_BufferedSocket {public static void main(String[] args) throws IOException {
        //1,连贯指定的服务器 -- 输出服务器 IP 地址和端口号
        // 本机 ip--127.0.0.1
        Socket socket = new Socket("127.0.0.1",8886);
        System.out.println("客户端连贯胜利");
        Test3_BufferedReader.writeline("./b.txt","over");
        Test3_BufferedReader.readline("./a.txt");    
    }

}

5JDK 新个性

JDK1.5– 可变长参数 (Varargs)method(int a,int…b)
JDK1.7–try–with–resources:主动敞开流
JDK1.8–Lambda 表达式

 应用 Lambda 语法来代替 匿名外部类,代码不仅简洁,而且还可读
语法:(参数列表) -> {办法体}
  -- 接口能够存在一般办法,然而须要用 default/static 润饰。
退出移动版