java语法基础2

Function

1.方法的重载

名字必须相同但参数列表必须不相同

image-20230130171438815

加了包以后编译出错的解决方案

2.可变参数

image-20230130173136767

可变参数必须要在所有参数的最后面

3.递归

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-S05d2NNi-1687312409321)(C:/Users/NM/AppData/Roaming/Typora/typora-user-images/image-20230130173313250.png)]

Demo:阶乘

package com.xx.function;

import java.util.Scanner;

public class Demo02 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个数:");
        int number = scanner.nextInt();
        System.out.println(number+"的阶乘为:"+f(number));
    }
    public static int f(int n) {
        if (n == 1) {
            return 1;
        } else {
            return n * f(n - 1);
        }
    }
}

程序执行过程

image-20230131112307422

注意点:对于递归调用,一定要写明其结束的条件,否则程序会无限的进行调用,会不断占用栈的资源

5.Array

image-20230131113624270

数组在内存里面的变化

image-20230131142656731

1.内存分配

  • :存放对象实例和数组
  • :基本数据类型和对象的引用
  • 方法区:类、静态方法、静态变量、常量、成员方法、常量池

image-20230131143029404

2.冒泡排序

//冒泡排序
//对数组中相邻的两个数进行比较,每次比较找出最大值或者最小值
    public static int[] bubbleSort(int[] number) {
        int temp;
        //外层循环表示比较的轮数
        for (int i = 0; i < number.length - 1; i++) {
//            System.out.println(number[i]);
            //内循环表示比较次数 每一轮都会出现一个最大值和最小值
            for (int j = 0; j < number.length - 1 - i; j++) {
                if (number[j] > number[j + 1]) {
                    temp = number[j];
                    number[j]= number[j+1];
                    number[j+1]=temp;
                }
            }
        }
        return number;
    }
}

3.稀疏数组

image-20230131160729918

package com.xx.array;

public class Demo02 {
    /**
     * ROW:行
     * COLUMN:列
     */
    final static int ROW = 11;
    final static int COLUMN = 11;

    public static void main(String[] args) {
        int[][] array = new int[ROW][COLUMN];
        array[1][2] = 1;
        array[2][3] = 2;
        System.out.println("原始数组:");
        printArray(array);
        int[][] result = sparseArrays(array);
        System.out.println("稀疏数组:");
        printArray(result);

    }

    /**
     * 打印数组
     *
     * @param array
     */
    public static void printArray(int[][] array) {
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array.length; j++) {
                System.out.print(array[i][j] + "\t");
            }
            System.out.println();
        }
    }

    public static int[][] sparseArrays(int[][] array) {
        //获取有效值的个数
        int value = 0;
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array.length; j++) {
                if (array[i][j] != 0) {
                    value++;
                }
            }
        }
        int[][] sparse = new int[value + 1][3];
        sparse[0][0] = ROW;
        sparse[0][1] = COLUMN;
        sparse[0][2] = value;
        //计数
        int count = 0;
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array.length; j++) {
                if (array[i][j] != 0) {
                    count++;
                    sparse[count][0] = i;
                    sparse[count][1] = j;
                    sparse[count][2] = array[i][j];
                }
            }
        }
        return sparse;
    }
}

OOP

本质:以类的方式组织代码,以对象的组织(封装)数据

特性:封装、继承、多态

1.构造器

在创建一个对象的时候,会默认的去创建一个无参构造

image-20230202105612833

2.内存图分析

image-20230202113412424

image-20230202145002981

3.继承(extends、Super)

image-20230202160116486

4.重写

需要继承关系,子类重写父类的方法!

  • 方法名必须相同

  • 参数列表必须相同

  • 方法体可以不同

  • 修饰符:范围可以扩大,不能缩小;常见:public>protected>default>private

    重写的原因:父类的功能,子类不一定需要,或者不一定满足

image-20230202161029261

5.多态

  • 一个类实际类型可以确定,但是引用类型是变化的

image-20230202163635599

注意点

1.多态是方法的多态,属性没有多态

2.父类和子类,有联系

3.存在条件:继承关系,方法需要重写,父类引用指向子类对象

  • static方法 不能重写,它是属于类的
  • final
  • private修饰的方法

6.static

和类一块加载

静态代码块

  • 执行顺序:静态代码块、匿名代码块、构造方法
  • 今天代码块只执行一次

7.抽象类(abstract)

  • 抽象方法:只有名字,没有实现的细节。抽象类的所有方法,子类都要实现
  • 抽象类不能创建,只能子类来实现
  • 抽象类里面的方法不一定为抽象方法,但是抽象方法一定要在抽象类里面

8.接口(interface)

  • 接口都要有实现类(implements)
  • 接口可以实现多继承
  • 实现接口,要重写接口的方法
  • 接口中的所有方法都是抽象的,都是public修饰的
  • 接口中定义的变量,通常为常量

9.Exception或Error

  1. 检查性异常
  2. 运行时异常
  3. 错误

image-20230203104110130

异常的捕获:(ctrl+alt+t)

try、catch、finally、throw(方法中)、throws(方法上)

Thread

线程的创建

1.继承Thread类,重写run()方法,开启start()
package com.xx.Thread;
/*
线程的创建方式一:
    继承Thread类,重写run方法,开启start,执行的顺序由cpu的调度安排
 */
public class TestThread01 extends Thread {
    //重写run方法
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("run线程" + i);
        }
    }

    public static void main(String[] args) {
        //创建线程
        TestThread01 testThread01 = new TestThread01();
        //开启线程
        testThread01.start();
        for (int i = 0; i < 1000; i++) {
            System.out.println("main线程" + i);
        }
    }
}

图片下载

package com.xx.Thread;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;

//图片下载
public class TestThread02 extends Thread {
    private String url;
    private String name;

    //构造器传递路径和名字
    public TestThread02(String url, String name) {
        this.url = url;
        this.name = name;
    }

    @Override
    public void run() {
        WebDownload webDownload = new WebDownload();
        webDownload.download(url, name);
        System.out.println(name+"下载完成");
    }

    public static void main(String[] args) {
        TestThread02 t1 = new TestThread02("https://cn.bing.com/images/search?view=detailV2&ccid=wc%2fdCG%2fK&id=2A67B025EDB55DFCC3EACFBF5B0CD513CC71AE39&thid=OIP.wc_dCG_KbIKZwMdtD3gL2QHaEt&mediaurl=https%3a%2f%2fpic3.zhimg.com%2fv2-58d652598269710fa67ec8d1c88d8f03_r.jpg%3fsource%3d1940ef5c&exph=1304&expw=2048&q=%e5%9b%be%e7%89%87&simid=607986392537319467&FORM=IRPRST&ck=7906E4DE8F66609504206A4E0B045F1E&selectedIndex=1", "01.jpg");
        TestThread02 t2 = new TestThread02("https://cn.bing.com/images/search?view=detailV2&ccid=YQ6LnR6c&id=9B613B6C54487D383AB606CCC723D63A20A6211C&thid=OIP.YQ6LnR6cs5xapSK8o0wChwHaEo&mediaurl=https%3a%2f%2fdesk-fd.zol-img.com.cn%2ft_s960x600c5%2fg1%2fM0B%2f03%2f06%2fChMljl402K6IOTZbAARWayFg6S4AAQJPwFhuRIABFaD752.jpg&exph=600&expw=960&q=%e5%9b%be%e7%89%87&simid=608041587144007854&FORM=IRPRST&ck=AD2923F3F781869FBFA5AAC4B03EB411&selectedIndex=3&ajaxhist=0&ajaxserp=0", "02.jpg");
        TestThread02 t3 = new TestThread02("https://cn.bing.com/images/search?view=detailV2&ccid=YKoZzgmu&id=702E280C47E9987874D231029BBBC2628E1A46C2&thid=OIP.YKoZzgmubNBxQ8j-mmoTKAHaEK&mediaurl=https%3a%2f%2fpic.3gbizhi.com%2f2019%2f0928%2f20190928012439343.jpg&exph=2592&expw=4608&q=%e5%9b%be%e7%89%87&simid=607999298888101361&FORM=IRPRST&ck=4BC2A0E29300968C1CE49D200C16DF25&selectedIndex=7&ajaxhist=0&ajaxserp=0", "03.jpg");
        t1.start();
        t2.start();
        t3.start();
    }
}

//下载器
class WebDownload {
    public void download(String url, String name) {
        try {
            FileUtils.copyURLToFile(new URL(url), new File(name));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("下载器异常");
        }
    }
}

工具类下载链接:(20条消息) 如何优雅地下载和使用Apache Commons_io_我想脱离小码农的博客-CSDN博客

2.实现Runnable接口
package com.xx.Thread;

public class TestThread03 implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("run线程" + i);
        }
    }
    public static void main(String[] args) {
        //创建Runnable实现类
        TestThread03 thread03 = new TestThread03();
        //实现Runnable接口
        new Thread(thread03).start();
        for (int i = 0; i < 1000; i++) {
            System.out.println("main线程" + i);
        }
    }
}

龟兔赛跑

package com.xx.Thread;

import sun.awt.windows.ThemeReader;

//龟兔赛跑
public class Race implements Runnable{
    private static String winner;
    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            //判断比赛是否结束
            boolean flag = gameOver(i);
            //兔子休息
            if(Thread.currentThread().getName()=="兔子" && i%10==0){
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
            if (flag) {
                break;
            }
            System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
        }
    }
    //是否完成比赛通过判断是否存在胜利者来判断
    public boolean gameOver(int steep){
        if (winner!=null){//存在胜利者
            return true;
        }else if (steep>=100){
            winner = Thread.currentThread().getName();
            System.out.println("Winner is "+winner);
        }
        return false;
    }

    public static void main(String[] args) {
        Race race = new Race();
        new Thread(race,"乌龟").start();
        new Thread(race,"兔子").start();
    }
}
3.实现Callable接口

image-20230203165405124

4.Lamda表达式
  • 函数式接口:接口里面只含有一个抽象方法
  • 函数式接口才能使用Lamda表达式
  • lambda表达式只有一行代码的情况下,可以去掉花括号,否则就要用其包裹
  • 多个参数也可以去掉,但是必须要加()
package com.xx.Thread;

public class Lamda {
    public static void main(String[] args) {
        Person p = (a)-> System.out.println("aa"+a);
        p.stuent(7);
    }
}
interface Person{
    void stuent(int a);
}

5线程的生命周期

创建–>就绪–>(阻塞)–>运行–>死亡

线程停止(利用标志位实现)

package com.xx.Thread;

//通过标志位来停止线程
public class TestStop implements Runnable {
    //标志位
    private boolean flag = true;

    @Override
    public void run() {
        int j = 0;
        while (flag) {
            System.out.println("Thrad....run" + j++);
        }
//        System.out.println("Thread");
    }

    public void stop() {
        this.flag = false;
    }

    public static void main(String[] args) {
        TestStop testStop = new TestStop();
        new Thread(testStop).start();
        for (int i = 0; i < 1000; i++) {
//            System.out.println("main"+i);
            if (i == 900) {
                testStop.stop();
//                System.out.println("Stop");
            }

        }
    }
}

6.Sleep、yield、State、Damon

模拟网络延时:放大问题的发生性

模拟倒计时

sleep不会释放线程锁

线程守护:用户线程、守护线程(一般情况都为用户线程)

7.线程同步

同步方法

同步代码块

package com.xx.Thread;

public class Bank {
    public static void main(String[] args) {
        Account account = new Account(1000, "存款");
        Drawing my = new Drawing(account, 500, "my");
        Drawing wife = new Drawing(account, 400, "wife");
        my.start();
        wife.start();
    }
}

//账户
class Account {
    //余额
    private int money;
    //卡名
    private String name;

    public Account(int money, String name) {
        this.money = money;
        this.name = name;
    }

    public int getMoney() {
        return money;
    }

    public String getName() {
        return name;
    }

    public void setMoney(int money) {
        this.money = money;
    }

    public void setName(String name) {
        this.name = name;
    }
}

//银行
class Drawing extends Thread {
    //账户
    Account account;
    //取走了多少钱
    int drawing;
    //手里多少钱
    int nowMoney;

    public Drawing(Account account, int drawing, String name) {
        super(name);
        this.account = account;
        this.drawing = drawing;
    }
    //取钱

    @Override
    public void run() {
        //锁的对象为变化的量
        synchronized (account) {
            //判断是否有钱
            if (account.getMoney() - drawing < 0) {
                System.out.println(Thread.currentThread().getName() + "没钱了");
                return;
            }
            //模拟网络延时
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //卡里的钱
            account.setMoney(account.getMoney() - drawing);
            //手里的钱
            nowMoney = nowMoney + drawing;
            //账户余额为
            System.out.println(account.getName() + "账户余额为" + account.getMoney());
            //手里的钱
            System.out.println(this.getName() + "手里的钱为" + nowMoney);
        }
    }
}

lock锁

image-20230213170206555

8.线程通信

生产者消费者问题

管程法

package com.xx.Thread;

//线程通信   管程法 (生产者,消费者问题)
public class TestPc {
    public static void main(String[] args) {
        SynContainer synContainer = new SynContainer();
        new Producer(synContainer).start();
        new Consumer(synContainer).start();
    }
}

//生产者
class Producer extends Thread {
    //缓冲区
    SynContainer synContainer;

    public Producer(SynContainer synContainer) {
        this.synContainer = synContainer;
    }

    //生产
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            synContainer.push(new Product(i));
            System.out.println("生产了第" + i + "个产品");
        }
    }
}

//消费者
class Consumer extends Thread {
    SynContainer synContainer;

    public Consumer(SynContainer synContainer) {
        this.synContainer = synContainer;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("消费了第"+synContainer.pop().id+"个产品");
        }
    }
}

//产品
class Product {
    //产品编号
    int id;

    public Product(int id) {
        this.id = id;
    }
}

//缓冲区
class SynContainer {
    //容器
    Product[] products = new Product[10];
    //计数器
    int count;

    //生产者放入产品
    public synchronized void push(Product product) {
        if (products.length == count) {
            //如果满了,生产者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //没有满,放入产品
        products[count] = product;
        count++;
        //通知消费者
        this.notifyAll();
    }

    //消费者消费产品
    public synchronized Product pop() {
        //判断能否消费产品
        if (count == 0) {
            //消费者等待,生产者生产
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //消费产品
        count--;
        //取出产品
        Product product = products[count];
        //通知生产者
        this.notifyAll();
        //返回产品
        return product;
    }
}

信号灯法

package com.xx.Thread;

//信号灯法
public class TestPC2 {
    public static void main(String[] args) {
        TV tv = new TV();
        new Player(tv).start();
        new Watcher(tv).start();
    }
}

//演员
class Player extends Thread {
    TV tv;

    public Player(TV tv) {
        this.tv = tv;
    }

    @Override
    public void run() {
        //表演20秒
        for (int i = 0; i < 20; i++) {
            if (i % 2 == 0) {
                tv.play("快了大本营");
            } else {
                tv.play("广告");
            }
        }
    }
}

//观众
class Watcher extends Thread {
    TV tv;

    public Watcher(TV tv) {
        this.tv = tv;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            tv.watch();
        }
    }
}

//电视
class TV {
    //节目
    String voice;
    //标志位
    boolean flag = true;

    //演员表演,观众等待 T
    //演员等待,观众观看 F
    //演员表演
    public synchronized void play(String voice) {
        if (!flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("演员表演了" + voice);
        //通知观众观看
        this.notifyAll();
        this.voice = voice;
        this.flag = !this.flag;
    }

    //观众观看
    public synchronized void watch() {
        if (flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("观众观看了" + voice);
        //通知演员表演
        this.notifyAll();
        this.flag = !this.flag;
    }
}

注解和反射

注解

内置注解
    
@Override:复写

@Deprecated:方法已经废弃,不推荐使用
   
@SuppressWarnings(“”):镇压警告
元注解

@Target:注解使用的范围

@Retention:注解的生命周期(SOURCE<CLASS<**RUNTIME**@Document:该注解包含在javadoc中

@Inherited:用于子类可以继承父类

image-20230307160913303

反射

一个类在内存中只有一个class对象

一个类被加载后,类的整个结构都会被封装在Class对象中

获取Class的方式

User user = new Student();
System.out.println("当前用户为"+user);
//方式一:通过对象获得
Class c1 = user.getClass();
System.out.println(c1.hashCode());
//方式二:通过forName()获得
Class c2 = Class.forName("com.xx.reflection.Student");
System.out.println(c2.hashCode());
//通过类名.class获得
Class<Student> c3 = Student.class;
System.out.println(c3.hashCode());
//方式四:基本类型的包装类都有一个Type属性
Class<Integer> c4 = Integer.TYPE;
System.out.println(c4.hashCode());
//获取父类属性
Class c5 = c1.getSuperclass();

所有类型的Class

//Object类
Class<Object> c1 = Object.class;
//接口
Class<Comparable> c2 = Comparable.class;
//一维数组
Class<String[]> c3 = String[].class;
//二维数组
Class<int[][]> c4 = int[][].class;
//注解
Class<Override> c5 = Override.class;
//枚举
Class<ElementType> c6 = ElementType.class;
//void
Class<Void> c7 = void.class;
//基本数据类型
Class<Integer> c8 = int.class;
//Class
Class<Class> c9 = Class.class;

类的加载

image-20230307180319308

image-20230308142317174

类的初始化

image-20230307181143239

类加载器

image-20230308141826180

package com.xx.reflection;

/**
 * 类加载器
 */
public class Test03 {
    public static void main(String[] args) throws ClassNotFoundException {
        //获取系统加载器
        ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
        System.out.println(systemClassLoader);
        //获取系统加载器的父类加载器-->扩展类加载器.
        ClassLoader parent = systemClassLoader.getParent();
        System.out.println(parent);
        //获取扩展类加载器的父类加载器-->根加载器(C/C++)
        ClassLoader parentParent = parent.getParent();
        System.out.println(parentParent);
        //测试当前类是那个加载器(通过反射)
        ClassLoader classLoader = Test03.class.getClassLoader();
        System.out.println(classLoader);
        //测试JDK内置的类是谁加载的
        ClassLoader loader = Class.forName("java.lang.Object").getClassLoader();
        System.out.println(loader);
        //获取系统类加载器可以加载的路径
        System.out.println(System.getProperty("java.class.path"));//根加载器
        /**
         * 双亲委派机制
         * 自己定义的类要加载,会先去用户类寻找是否有这个包,如果没有再去扩展类
         * 加载器去寻找,如果没有就会根加载器寻找
         * 双亲委派机制,多重检测,保证安全性
         */

    }
}

获取类的信息

package com.xx.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 获取类的信息
 */
public class Test04 {
    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
        //反射获得Class
        Class<User> userClass = User.class;
        //获得类的名字
        //包名+类型
        System.out.println(userClass.getName());
        //简单类名
        System.out.println(userClass.getSimpleName());
        //获得类的属性
        /**
         *        userClass.getFields();  获得公共属性
         *         userClass.getDeclaredFields(); 获得所有属性
         */
        for (Field field : userClass.getDeclaredFields()) {
            System.out.println(field);
        }
        //获得指定属性
        System.out.println(userClass.getDeclaredField("name"));
        //获得类的方法
        /**
         *         userClass.getMethods(); 获得本类及其父类的全部public方法
         *         userClass.getDeclaredMethods(); 获得本类的所有方法
         */
        for (Method method : userClass.getDeclaredMethods()) {
            System.out.println(method);
        }
        //获得指定方法
        //获取方法的时候,除了写明方法名,还要写明方法的参数类型
        System.out.println(userClass.getDeclaredMethod("getName", null));
        //获取构造器
        for (Constructor<?> constructor : userClass.getDeclaredConstructors()) {
            System.out.println(constructor);
        }
        //获得指定的构造器
        System.out.println(userClass.getDeclaredConstructor(String.class, int.class, int.class));
    }
}

通过反射创建对象并操作属性和方法

package com.xx.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test05 {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        //获得Class对象
        Class<User> userClass = User.class;
        //构造一个对象 使用newInstance创建对象  使用的是无参构造器
        User user = userClass.newInstance();
        System.out.println(user);

        //通过构造器创建对象
        Constructor<User> constructor = userClass.getDeclaredConstructor(String.class, int.class, int.class);
        User user1 = constructor.newInstance("张三", 001, 18);
        System.out.println(user1);
        //通过反射调用方法
        User user2 = userClass.newInstance();

        //通过反射获取一个方法
        Method setName = userClass.getDeclaredMethod("setName", String.class);
        //invoke:激活  参数(对象,"方法值")
        setName.invoke(user2, "zhangsan");
        System.out.println(user2.getName());

        //通过反射操作属性
        //对于属性,我们不能直接操作私有的属性,它存在安全检测,可以通过seAccessible(true)关闭
        User user3 = userClass.newInstance();
        Field name = userClass.getDeclaredField("name");
        name.setAccessible(true);
        name.set(user3,"李四");
        System.out.println(user3.getName());

    }
}

newInstance():创建的对象使用的是无参构造器

私有化的方法和属性要使用setAccessible(true),不然就会报错

在性能上,反射创建对象的性能没有new的高

反射获取泛型

image-20230308153518061

package com.xx.reflection;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

public class Test06 {
    public static void test01(Map<String, User> map, List<Integer> list) {
        System.out.println("test01");
    }

    public static Map<String, User> test02() {
        System.out.println("test02");
        return null;
    }

    public static void main(String[] args) throws NoSuchMethodException {
        //通过反射获取方法
        Method method = Test06.class.getDeclaredMethod("test01", Map.class, List.class);
        //获取方法的参数类型
        /**
         * getGenericParameterTypes:返回Type类型的数组 Type[].
         * getParameterTypes:返回Class类型的数组: Class<?>[].
         */
        Type[] types = method.getGenericParameterTypes();
        for (Type type : types) {
            System.out.println(type);
            //判断type类型是否属于参数化类型
            if (type instanceof ParameterizedType) {
                //将type类型转化为参数化类型并且获得它真实类型的数组
                for (Type actualTypeArgument : ((ParameterizedType) type).getActualTypeArguments()) {
                    System.out.println(actualTypeArgument);
                }
            }
        }
        
        
        //获取返回值类型
        Method methods = Test06.class.getDeclaredMethod("test02",null);
        Type genericReturnType = methods.getGenericReturnType();
        if (genericReturnType instanceof ParameterizedType){
            for (Type actualTypeArgument : ((ParameterizedType) genericReturnType).getActualTypeArguments()) {
                System.out.println(actualTypeArgument);
            }
        }



    }
}

getGenericParameterTypes和getParameterTypes区别:https://blog.csdn.net/u013066244/article/details/102997214

通过反射获得注解

package com.xx.reflection;

import java.lang.annotation.*;
import java.lang.reflect.Field;

public class Test07 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class c1 = Class.forName("com.xx.reflection.Students");
        //获得注解
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
        //获得注解的value值
        TableStudent annotation = (TableStudent)c1.getAnnotation(TableStudent.class);
        String name = annotation.name();
        System.out.println(name);
//        TableStudent tablemi = (TableStudent)c1.getAnnotation(TableStudent.class);
//        String value = tablemi.value();
//        System.out.println(value);
        //获得属性的注解
        //获得属性
        Field name1 = c1.getDeclaredField("id");
        FieldStudent annotation1 = name1.getAnnotation(FieldStudent.class);
        System.out.println(annotation1.columnName());

    }
}
@TableStudent(name = "db_student")
class Students{
    @FieldStudent(columnName = "db_id",type = "int",length = 10)
    private int id;
    private String name;
    private int age;

    public Students() {
    }

    public Students(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setId(int id) {
        this.id = id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableStudent{
    String name();

}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldStudent{
    String columnName();
    String type();
    int length();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值