注解Annotation

注解很厉害,它可以增强我们的java代码,同时利用反射技术可以扩充实现很多功能。它们被广泛应用于三大框架底层。传统我们通过xml文本文件声明方式,而现在最主流的开发都是基于注解方式,代码量少,框架可以根据注解去自动生成很多代码,从而减少代码量,程序更易读。例如最火爆的SpringBoot就完全基于注解技术实现。

分类

JDK自带注解
元注解
自定义注解

JDK注解

@Override
@Deprecated标记就表明这个方法已经过时了,但我就要用,别提示我过期
@SuppressWarnings(“deprecation”) 忽略警告
@SafeVarargs jdk1.7出现,堆污染,不常用
@FunctionallInterface jdk1.8出现,配合函数式编程拉姆达表达式,不常用

元注解

@Target 注解用在哪里:类上、方法上、属性上
@Retention 注解的生命周期:源文件中、class文件中、运行中
@Inherited 允许子注解继承
@Documented 生成javadoc时会包含注解,不常用
@Repeatable注解为可重复类型注解,可以在同一个地方多次使用,不常用

@Target

用于指定被修饰注解的修饰目标类型。如果一个注解明确了可修饰的目标类型,则只能修饰指定的类型。由枚举ElementType来规定。
–ElementType.ANNOTATION_TYPE 应用于
–ElementType.CONSTRUCTOR 应用于构造函数
–ElementType.FIELD 应用于字段或属性
–ElementType.LOCAL_VARIABLE 应用于局部变量
–ElementType.METHOD 应用于方法级
–ElementType.PACKAGE 应用于包声明
–ElementType.PARAMETER 应用于方法的参数
–ElementType.TYPE 应用于类的元素

@Retention

定义了该注解被保留的时间长短,某些注解仅出现在源代码中,而被编译器丢弃;
而另一些却被编译在class文件中; 编译在class文件中的注解可能会被虚拟机忽略,而另一些在class被装载时将被读取。
–SOURCE 在源文件中有效(即源文件保留)
–CLASS 在class文件中有效(即class保留)
–RUNTIME 在运行时有效(即运行时保留)

代码演示

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;//测试 自定义注解
public class Test_Annotation {public static void main(String[] args) {}
}//一,自定义注解: @interface 注解名//@Target(ElementType.TYPE)//描述注解可以出现的位置--只能类上用@Target({ ElementType.TYPE, ElementType.METHOD })//描述注解可以出现的位置--多个位置上用@Retention(RetentionPolicy.SOURCE)//描述注解的生命周期@interface Test{//1,给注解添加功能--属性--语法特殊//String local();String local() default "" ;//3,给属性设置默认值,方便直接使用@TestString value() default "" ; //5,特殊的属性value}//二,使用注解: @Test//@Test(local = "class")//2,当Test注解添加了属性时,而且,属性又没设置默认值时,需要给属性赋值//@Test//4,由于属性设置好了默认值,用时就简单了@Test("123")//6,由于value属性比较特殊,可以简写.赋值时省略掉value=class Hello{//@Test//位置非法,不能出现String name;@Test(local = "method",value = "???")//7,给多个属性赋值时,不能省略value=public void show(){System.out.println("show()");}}

反射Reflect

Reflection(反射) 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说“自审”,也有称作“自省”。反射非常强大,它甚至能直接操作程序的私有属性。我们前面有一个概念,private的只能类内部访问,外部是不行的,但这个规定被反射赤裸裸的打破了。
反射就像一面镜子,它可以在运行时获取一个类的所有信息,可以获取到任何定义的信息(包括成员变量,成员方法,构造器等),并且可以操纵类的字段、方法、构造器等部分。

常用方法

获得包名、类名
clazz.getPackage().getName()//包名
clazz.getSimpleName()//类名
clazz.getName()//完整类名

成员变量定义信息
getFields()//获得所有公开的成员变量,包括继承的变量
getDeclaredFields()//获得本类定义的成员变量,包括私有,不包括继承的变量
getField(变量名)
getDeclaredField(变量名)

构造方法定义信息
getConstructor(参数类型列表)//获得公开的构造方法
getConstructors()//获得所有公开的构造方法
getDeclaredConstructors()//获得所有构造方法,包括私有
getDeclaredConstructor(int.class, String.class)

方法定义信息
getMethods()//获得所有可见的方法,包括继承的方法
getMethod(方法名,参数类型列表)
getDeclaredMethods()//获得本类定义的方法,包括私有,不包括继承的方法
getDeclaredMethod(方法名, int.class, String.class)

反射新建实例
c.newInstance();//执行无参构造
c.newInstance(6, “abc”);//执行有参构造
c.getConstructor(int.class, String.class); //执行含参构造,获取构造方法

反射调用成员变量
c.getDeclaredField(变量名); //获取变量
c.setAccessible(true); //使私有成员允许访问
f.set(实例, 值); //为指定实例的变量赋值,静态变量,第一参数给 null
f.get(实例); //访问指定实例的变量的值,静态变量,第一参数给 null

反射调用成员方法
Method m = c.getDeclaredMethod(方法名, 参数类型列表);//获取方法
m.setAccessible(true) ;//使私有方法允许被调用
m.invoke(实例, 参数数据) ;//让指定的实例来执行该方法

代码演示

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;//测试 反射 获取Class对象
public class Test_ReflectStudent {public static void main(String[] args) throws Exception {method();//获取Class对象method2();//获取构造方法method3();//获取成员方法method4();//获取成员变量method5();// 通过反射的技术创建对象}// 创建对象public static void method5() throws Exception {// 1,获取Class对象Class<Student> clazz = Student.class;// 2,调用实例化方法 --也要触发构造方法,而且触发的是无参构造// newInstance()必须提供无参构造,否则[抛出异常:java.lang.InstantiationException:// cn.tedu.reflect.StudentStudent s = clazz.newInstance();System.out.println("s = " + s);// 重写toString()前:s = cn.tedu.reflect.Student@1b6d3586// 重写toString()后:s = Student{name='null', age=0, score=0.0}// 怎么触发含参构造--触发public Student(String name)// getConstructor(m);--m参数要 匹配构造方法里 参数的类型 的Class对象Constructor<Student> c = clazz.getConstructor(String.class);// 指定// newInstance(x)--x是你创建对象时具体的参数Student s2 = c.newInstance("jack");System.out.println("s2 = " + s2);// TODO 触发public Student(String name, int age)Constructor<Student> c2 = clazz.getConstructor(String.class, int.class);Student s3 = c2.newInstance("xiongda", 20);System.out.println("s3 = " + s3);}// 获取成员变量public static void method4() {// 1,获取Class对象Class clazz = Student.class;// 2,获取所有成员变量 -- 只能获取公开的变量Field[] fs = clazz.getFields();// 3,遍历数组,得到每个变量ffor (Field f : fs) {// 4,获取变量名称System.out.println(f.getName());// 5,获取变量类型System.out.println(f.getType().getName());}}// 获取成员方法public static void method3() {// 1,获取Class对象Class<Student> clazz = Student.class;// 2,获取所有成员方法们 -- 包括自己的和父类的 的公开的方法们Method[] ms = clazz.getMethods();// 3,遍历数组,得到每个方法mfor (Method m : ms) {// 4,获取方法名称System.out.println(m.getName());// 5,获取方法的参数的类型Class<?>[] cs = m.getParameterTypes();System.out.println(Arrays.toString(cs));}}// 获取构造方法public static void method2() {// 1,获取Class对象 --封装了.class文件里的所有数据Class clazz = Student.class;// 2,获取所有构造方法们 , 并存入数组 -- 只能反射 公开的 资源Constructor[] cs = clazz.getConstructors();// 3,获取每个构造方法cfor (Constructor c : cs) {// 4,获取构造方法的名字System.out.println(c.getName());// 5,获取构造方法的参数类型 们Class[] css = c.getParameterTypes();System.out.println(Arrays.toString(css));}}// 获取Class对象public static void method() throws ClassNotFoundException {Class c = Class.forName("cn.tedu.reflect.Student");// 参数是类的全路径Class c2 = Student.class;Class c3 = new Student().getClass() ;//使用了父类Object提供的getClass()System.out.println("c3 = " + c3);System.out.println("c2 = " + c2);System.out.println("c = " + c);}
}

暴力反射

不仅能获取到类的public资源,也可以获取到类里的private资源
普通反射
–getConstructor()
–getConstructors()
–getMethod()
–getMethods()
–getField()
–getFields()

暴力反射
–getDeclaredConstructor()
–getDeclaredConstructors()
–getDeclaredMethod()
–getDeclaredMethods()
–getDeclaredField()
–getDeclaredFields()

代码演示

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;//测试 暴力反射:
//条件 : 使用getDeclaredXxx()  + 开启私有可见的权限
public class Test_BaoliReflect {public static void main(String[] args) throws Exception {method();//暴力反射成员方法们method2();// 暴力反射成员变量}// 暴力反射成员变量们public static void method2() throws Exception {// 1,获取Class对象Class clazz = Person.class;// 2,暴力反射Field[] fs = clazz.getDeclaredFields();// 3,遍历数组,得到每个变量ffor (Field f : fs) {// 4,获取变量名称System.out.println(f.getName());// 5,获取变量类型System.out.println(f.getType().getName());}// 获取指定的变量Field f = clazz.getDeclaredField("score");// 开启 访问权限,否则访问私有抛出异常:IllegalAccessException:f.setAccessible(true);Object obj = clazz.newInstance();// 设置值--set(1,2)--1是指对象名称--2是要设置的具体值f.set(obj, 99.9);// 获取值--get(1)--1是指对象名称System.out.println(f.get(obj));}// 暴力反射成员方法们public static void method() throws Exception {// 1,获取Class对象Class<Person> clazz = Person.class;// 2,暴力反射 -- getDeclaredMethods()Method[] ms = clazz.getDeclaredMethods();// 3,遍历数组,得到每个方法mfor (Method m : ms) {// 4,获取方法名称System.out.println(m.getName());// 5,获取方法的参数的类型Class<?>[] cs = m.getParameterTypes();System.out.println(Arrays.toString(cs));}// 暴力反射 某个方法// getDeclaredMethod(1,2)--获取指定的方法// --1是指方法名--2是指方法需要的参数类型的Class对象Method m = clazz.getDeclaredMethod("game", String.class);// 暴力反射:除了用对API,另外还需要开启访问权限m.setAccessible(true);Object obj = clazz.newInstance();// 执行方法--invoke(1,2)--1是指对象名称--2是方法需要传入的参数m.invoke(obj, "tony");}
}

内部类

如果一个类存在的意义就是为指定的另一个类,可以把这个类放入另一个类的内部。就是把类定义在类的内部的情况就可以形成内部类的形式。
A类中又定义了B类,B类就是内部类。B类可以当做A类的一个成员看待。
特点
1、 内部类可以直接访问外部类中的成员,包括私有成员
2、 外部类要访问内部类的成员,必须要建立内部类的对象
3、 在成员位置的内部类是成员内部类
4、 在局部位置的内部类是局部内部类

//测试 内部类
public class Test_Inner {public static void main(String[] args) {// TODO 调用内部类的资源 --创建内部类对象// 语法: 外部类名.内部类名 变量名 = 外部类对象.内部类对象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()");}}
}

匿名内部类

匿名内部类属于局部内部类,并且是没有名字的内部类。

//测试 匿名内部类
//总结
//1,接口也可以直接new,但是要配合  匿名 内部类 ,完成抽象方法的重写 !!
public class Test_Inner2 {public static void main(String[] args) {// TODO 2,优化方案:直接new接口,要配合匿名内部类使用(在内部类里重写抽象方法)!!new Inter() {@Overridepublic void save() {System.out.println("数据保存成功!");}@Overridepublic void delete(int id) {System.out.println("数据删除成功!,id是:" + id);}}.save();// 调用指定方法// 4,给匿名对象起个名字 !!! -- 方便使用同一个对象干多个事情 !!!Inter in = new Inter() {@Overridepublic void save() {System.out.println("数据保存成功!");}@Overridepublic void delete(int id) {System.out.println("数据删除成功!,id是:" + id);}};// 5,使用有名字的同一个对象 ,干两件事in.save();in.delete(10);}
}
interface Inter{//简写形式void save() ;void delete(int id);
}
//TODO 1,可以优化 ...
class InterImpl implements Inter{@Overridepublic void save() {System.out.println("数据保存成功!");}@Overridepublic void delete(int id) {System.out.println("数据删除成功!,id是:"+id);}
}

Socket编程

在网络间,完成数据的传输. 把数据抽象的在网络间传递.对于电脑来讲,都可以完成收和发的过程.socket通信,本质上就是把数据 抽象成 IO流的形式在网路中传输

服务器端-ServerSocket

在服务器端,选择一个端口号,在指定端口上等待客户端发起连接。
启动服务:ServerSocket ss = new ServerSocket(端口);
等待客户端发起连接,并建立连接通道:Sokcet socket = ss.accept();

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;//socket通信的服务器端
public class Server {public static void main(String[] args) throws IOException {// 1,开启服务器 -- 端口号0~65535// 在指定的8000端口号处,等待客户端的连接ServerSocket server = new ServerSocket(8000);System.out.println("服务器已开启...");// 2,接收客户端连接请求,并建立通信通道SocketSocket socket = server.accept();System.out.println("接收一个客户端的请求...");// 3,读取客户端发来的数据InputStream in = socket.getInputStream();// 读到的数据默认是int,转成字符类型for (int i = 0; i < 5; i++) {char b = (char) in.read();System.out.print(b);// 同行展示}// 4,服务器给客户端发送数据OutputStream out = socket.getOutputStream();// 写出 动态的 数据System.out.println("请输入想要发送给客户端的数据:");String input = new Scanner(System.in).nextLine();out.write(input.getBytes());// String->byte[]out.flush();}
}

客户端-Socket

新建Socket对象,连接指定ip的服务器的指定端口
Socket s = new Socket(ip, port);
从Socket获取双向的流
InputStream in = s.getInputStream();
OutputStream out = s.getOutputStream();

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;//socket通信的客户端
public class Client {public static void main(String[] args) throws IOException {// 1,连接 定 ip地址 和 端口 的服务器// 实际工作中,要写服务器的真实ip -- 本机ip--127.0.0.1Socket socket = new Socket("127.0.0.1", 8000);System.out.println("客户端与服务器连接成功...");// 2,给服务器写出数据OutputStream out = socket.getOutputStream();// 写出 动态的 数据System.out.println("请输入想要发送给服务器的数据:");String input = new Scanner(System.in).nextLine();out.write(input.getBytes());// String->byte[]out.flush();// 3,读取服务器发来的数据InputStream in = socket.getInputStream();// 读到的数据默认是int,转成字符类型for (int i = 0; i < 5; i++) {char b = (char) in.read();System.out.print(b);// 同行展示}}
}

JAVASE----基础(七)相关推荐

  1. java学习之路之javaSE基础1

    <h2>java学习之路之javaSE基础1</h2> <div> ###01.01_计算机基础知识(计算机概述)(了解) * A:什么是计算机?计算机在生活中的应 ...

  2. 【JavaSE 基础知识盲点小结】

    [JavaSE 基础知识盲点小结] 一.第一天: 1. 在 cmd 命令窗口问题: ①编译是: javac HelloWorld.java ②运行时是: java HelloWorld (类名 不加 ...

  3. 面向对象-----6(javaSE基础知识完结篇)

    目录 解析面向对象 内存分析 三大特性.封装.继承.多态 接口 内部类 涉及知识目录总览: 资料来自于马士兵java笔记 这是javaSE基础知识的最后一篇笔记 1. 解析面向对象 返回目录 [1]面 ...

  4. Java面试题全集(上)+JavaSE基础

    三重:代码.底层内存.源码 第一阶段:开发常用 JavaSE基础.IDE.Maven.Gradle.SVN.Git.Spring.Spring MVC.Spring Boot.Spring Cloud ...

  5. javaSE基础04

    javaSE基础04 一.三木运算符 <表达式1> ? <表达式2> : <表达式3> "?"运算符的含义是: 先求表达式1的值, 如果为真, ...

  6. javase基础socket编程之局域网聊天,局域网文件共享

    2017年06月04日  23点25分 javase基础学完可以做什么,javase实现局域网聊天室 包含内容:基础语法,面向对象,多线程,IO流,GUI编程,网络编程(udp) 实现功能:局域网群聊 ...

  7. C++学习基础七——深复制与浅复制

    C++学习基础七--深复制与浅复制 一.深复制与浅复制基本知识 深复制和浅复制,又称为深拷贝和浅拷贝. 深复制和浅复制的区别如下图1所示: 图1 图1表示的是,定义一个类CDemo,包含int a和c ...

  8. JAVASE基础模块十五(StringBuffer类)

    JAVASE基础模块十五(StringBuffer类) public class Stbuffer { public static void main(String[] args) { //总共创建五 ...

  9. JAVASE基础模块三十四( 菜鸡版简单登录验证模块系统IO流文件写入)

    JAVASE基础模块三十四( 菜鸡版简单登录验证模块系统IO流文件写入) 开发流程:需求文档 接口文档 效果图 开发环境统一:JDK1.8 IDEA win10 GIT SSM SSH SpringB ...

  10. JAVA基础七 类和对象

    文章目录 JAVA基础七 类和对象 01 引用 02 继承 03 方法重载 04 构造方法 05 this 06 传参 07 包 08 访问修饰符 09 类属性 10 类方法 11 属性初始化 12 ...

最新文章

  1. private关键字 java 1613808402
  2. 结构体与共用体05 - 零基础入门学习C语言57
  3. 2016年中国微信小程序专题研究报告
  4. EPSnbsp;QOS体系图的解读
  5. win 8.1 安装framework3.5
  6. Linux下java获取屏幕分辨率,关于Android如何获取屏幕分辨率的例子
  7. 图片片转换成位深度为1的单色bmp照片
  8. iOS常见的加密方法有哪些
  9. python安装numpy模块教程_Python中Numpy包的安装与使用方法简明教程
  10. 计算机简历个人优势,简历个人优势怎么写
  11. 剪辑器更新-去水印详解
  12. C. Dominant Piranha(思维) Codeforces Round #677 (Div. 3)
  13. java商城管理系统_带数据库_带界面化可用来毕业设计
  14. 最新唯美520表白纪念网页HTML源码+UI超级好看
  15. 【题解】P2678 [NOIP2015 提高组] 跳石头
  16. vue3中的watch和watchEffect
  17. 瑞士酒店管理大学计算机专业,瑞士DCT国际酒店管理学院生活费用详细介绍
  18. 网络安全法及个人信息法律解读
  19. php图片轮换功能,微信小程swiper组件实现图片轮播切换功能教程
  20. GitChat · 人工智能 | 如何零基础用 Keras 快速搭建实用深度学习模型

热门文章

  1. OAM EFM原理总结
  2. MySQL【六】约束条件
  3. 4.3.1 国外LCA数据库 Foreign LCA Database
  4. 清华计算机系唐杰,清华大学——唐杰:图神经网络 (GNN) 及认知推理
  5. curl怎么输出赋值_触摸屏与PLC通讯不上?老师告诉你怎么办
  6. 连接服务器失败请与系统管理员联系,帮助_不能连接到服务器。本地端口被禁止,请与本地网络管理员联系。(访问端口:5005)_鹏保宝...
  7. 一个程序员老总的年终总结2009版
  8. 学习素材之USART篇——通过使用STM32与ESP8266(esp-01s)连接阿里云系列操作来了解USART协议和寄存器操作
  9. 使用RTL-SDR收听FM广播
  10. 超级计算机鲁大师跑分,PDD新电脑再次翻车,8w配的电脑当天就出问题,跑分才不到40万!...