JAVA基础半天速通集锦(only 40点,查找and复习必看)

JAVASE

以下内容根据【尚硅谷】7天搞定Java基础,Java零基础极速入门 视频简单总结而成
在这里插入图片描述
所谓变量就是可以改变的向量存储;标识符即标识数据的符号——变量名:只有下划线和$,预定义关键字或保留字不给用
在这里插入图片描述

  1. 基本数据类型 byte 8,short 16,int,long 64, float f = 1.0F; 范围小的数据转换为大的没问题,但大到小需要
    引用数据类型 类:对象是将内存地址赋值给了变量,所以变量其实是引用了内存中的对象,所以称之为引用变量
    String,接口,数组,枚举,特殊类型值:null

  2. &与运算,&&短路与运算:会根据第一个条件表达式结果来判断是否执行第二个条件表达式

  3. 先声明类(声明属性和方法),创建对象(main里),再执行方法
    如图所示,User user变量储存在栈中,而new User()这个对象在堆中,User类则存在元空间里。
    在这里插入图片描述

  4. 属性无需初始化,在构造对象的时候JVM会帮助我们自动初始化0,0.0, false,“”,null

  5. 参数个数不确定(0-n),但类型相同时:参数类型… 参数名称;如 (String… name);可变参数声明在最后

  6. 在这里插入图片描述
    方法和变量的修改无非就是压栈弹栈,因此无法传递改变值;而引用数据类型是传递内存地址,因此可改成"abc10",此外如User.name

  7. 把与对象无关,只和类相关称之为静态;静态方法不可访问成员属性和方法,反之可以;类的信息加载完成后自动调用静态代码块{不用构建对象直接调用class名称即可,而普通代码块需要new一下才会执行}

  8. java.lang包不用import;先package,再import; 构造方法用于构建对象,但构建对象后才会用它初始化,一般其参数用于赋初值

  9. 类型角度来看,多个子类继承的是一个父类; 继承需先构建父类对象(但每个子类继承的是父类属性和方法开辟的新内存空间,而不是真正完全一致的父类对象)再构建子类对象;父类有参构造需在子类构造方法中使用super(参数);

  10. 所谓的多态,其实就是一个对象在不同场景下表现出来的不同状态和形态; 多态语法其实就是对对象的使用场景进行约束:取决于声明对象自己
    {子类继承了父类所有,在需要时可以当成父类来用 Person p1 = new Boy(); 但此时无法调用Boy自己独有的功能函数 }

  11. 多态:一个类中,不能重复声明相同的方法和属性;但可以根据参数列表(个数 顺序 类型)来区分;构造方法亦可重载;在一个构造方法里还可通过this调用其他的构造方法。

  12. 基本数据类型在匹配方法的时候,可以在数值不变的情况下,扩大数据的精度,比如byte b = 10; test(short b);
    但Byte无法和char类型(16位)做转换,因为char没有负数,而byte存在负数

  13. 方法重写要保证,子类和父类方法名相同,返回类型相同,参数列表相同(构造方法不行)
    在10最后一句的基础上:一个对象能使用什么方法(CCC or DDD类)或属性(i),取决于引用变量的类型 CCC ddd = new DDD();
    但一个对象的方法的具体使用(直接间接)时需要看具体的对象的(有DDD用DDD,没就用CCC的方法) CCC ddd = new DDD();属性的具体使用不看具体对象,在哪声明在哪 用(默认有this.)
    //简而言之子类没有该方法 会逐步向上调用BBB->AAA->Object(可以是重载的)

  14. Java源码中public类(公共任意使用)只能有一个,而且必须和源码文件相同;main方法是JVM调用,不考虑权限问题
    private:同一个类中可以使用,声明对象不可调用;default即是JVM默认提供包(路径)权限,但在其他包下面无法调用;protected子类可以访问;
    私有:同类,默认:同类同包(路径),受保护:同类,同包(路径),子类{自己父亲保护自己孩子,只能访问public class的Object,而不是新声明对象的Object}、
    访问权限其实就是访问属性,方法的权力和限制

  15. Java中不允许用private和protected声明外部类;内部类当成外部类的属性即可,所以需要构建外部类.内部类使用

  16. 单例模式:由于类的创建过程复杂,类的对象消耗资源
    在这里插入图片描述

  17. 使用final修饰变量,数据初始化后不被修改{常量or不可变量};但修饰属性值,需要手动内部初始化或者使用构造函数中this.name=name来外部传参初始化;
    也可修饰方法,但不可被子类重写(不可修饰构造方法:无意义,也可修饰方法参数,方法中不可修改);修饰类也行,但就没有子类

  18. 分析问题: 对象(具体) ==> 类(抽象) ; 编写代码: 类(抽象) ==> 对象(具体);
    抽象类{抽象方法无大括号,但也可以有非抽象方法} 因为不完整无法构建对象,只能被继承,通过子类间接构建对象,同时也需要重写抽象方法补充完整。00…0
    abstract不能和final同时使用(方法无法重写,类没有子类)

  19. 接口可以简单理解为规则 interface 接口名称 {规则属性, 规则的行为} 其实是抽象
    规则的属性必须是静态 固定值,而且不能修改(和对象无关); 行为是抽象的,(由每个对象自行决定)。属性和行为的访问权限必须是公共的。
    接口和类是两个层面上的东西。接口可以继承其他接口,类的对象需要遵循接口/实现(implements)多个接口。

  20. 枚举类包含的特定对象一般不会改变,全大写标识符,和后面语法用分号隔开。枚举类不能创建对象,它的对象是在内部自行创建
    匿名类:在某些场合下,类的名字不那么重要,我们只想使用类中的方法或功能
    在这里插入图片描述

  21. 编写逻辑用bean建立数据模型,属性私有化 set和get;如果属性和(局部)变量名称相同,访问时不加修饰会优先访问变量.Object可用的一些方法如下
    在这里插入图片描述

  22. 数组(for循环练习,打印中心对称的九层妖塔:其实就是等腰三角形)
    在这里插入图片描述

  23. char[]和byte[]可直接传入String,但三个字节表示中文汉字,byte需要new String(bs,“UTF-8”)传入
    StringBuilder

char[] chars = s6.toCharArray();  byte[] bytes = s6.getBytes("UTF-8");
StringBuilder s = new StringBuilder();
for(int j=0;j<100;j++) s.append(j);//效率高,底层用数组方式构建,而不是拼接
System.out.println(s.toString());
  1. 除了八个基本数据类型外还有引用数据类型(String Array),均继承Object,可以构建对象,调用属性和方法实现一些操作。因此,提供了八个与之对应的包装类 引用数据类型。
Byte b = null; Short s = null; Integer i = null; Long lon = null;
Float f = null; Double d = null; Character c = null; Boolean bln = null;
int i1 = 10;
Integer i2 = Integer.valueOf(i1);
Integer i3 = i1; //自动装箱
int i4 = i2.intValue();
int i5 = i2; //自动拆箱
i2.byteValue();i2.compareTo(i3);i2.doubleValue();
  1. 日期和日历
//日期类
Date date = new Date(); //日期格式不太好理解 Tue Feb 21 00:00:00 CST 2023
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); //yyyy-MM-dd HH:mm:ss.SSS
String dateFormatString = sdf.format(date); //转换成日期格式化的字符串
String dateString = "2023-02-21"; //注意 和上方new SimpleDateFormat()内格式相同
Date parseDate = sdf.parse(dateString); //String -> Date
date.setTime(System.currentTimeMillis()); //根据时间戳构建指定的日期对象
date.getTime(); //获取时间戳
parseDate.before(date); parseDate.after(date);// 解析的时间早/晚于date的时间则是true
//日历类
Calendar instance = Calendar.getInstance(); // 这是抽象类无法构建实例对象,用getInstance静态方法 --- 单例模式
instance.get(Calendar.YEAR);
instance.get(Calendar.MONTH); //月份从0开始
instance.get(Calendar.DAY_OF_MONTH); instance.get(Calendar.DAY_OF_WEEK);
instance.setTime(date); instance.setTime(new Date());  //传指定日期过来,改日历
instance.add(Calendar.YEAR,-1); //当前日历-1年
static void printCalendar(){
    
     //打印日历
        System.out.println("一\t二\t三\t四\t五\t六\t日");
        //把日历对象设定为当前月的第一天
        Calendar firstDate = Calendar.getInstance();
        firstDate.set(Calendar.DAY_OF_MONTH,1);
        int maxDay = firstDate.getActualMaximum(Calendar.DAY_OF_MONTH); //一个月最大天数
        for (int i = 0; i < maxDay ; i++){
    
    
            int weekX = firstDate.get(Calendar.DAY_OF_WEEK); //一周当中第几天;周日是1,周一是2..周六是7
            int monthY = firstDate.get(Calendar.DAY_OF_MONTH); //一月当中第几天
            if (i==0){
    
     // 第一天,前面加\t,周日+6个
                if (weekX == Calendar.SUNDAY){
    
     //周日,轮转
                    for (int j = 0;j < 6;j++)
                        System.out.print("\t");
                    System.out.println(monthY);
                }else {
    
    
                    for (int j = 0;j < weekX-2;j++)
                        System.out.print("\t");
                    System.out.print(monthY+"\t");
                }
            }else {
    
    
                if (weekX == Calendar.SUNDAY){
    
     //周日,轮转
                    System.out.println(monthY);
                }else if(monthY == maxDay){
    
    
                    System.out.print(monthY+"\n");
                } else{
    
    
                    System.out.print(monthY+"\t");
                }
            }
            firstDate.add(Calendar.DATE,1);
        }
    }
  1. 工具类是公共静态且丰富的,在基本数据类型中,== 比较值,在引用数据类型则是比较变量内存地址,因此用.equals()更好,String会自动将 ==优化成比较值,但如果是new出来的和原来的则不等。类则需要重写equals方法{ 引用数据类型和包装类用equals}
int i = 10; double j = 10.0;
System.out.println(i==j); //true
String s1 = "abc"; String s2 = new String("abc");
System.out.println(s1 == s2); //false
User7 user1 = new User7();
User7 user2 = new User7();
System.out.println(user1 == user2); //false
System.out.println(user1.equals(user2)); //false ;继承父类的equals,其内核还是 双等号,除非重写
//包装类和引用数据类型都用equals
Integer i1 = 127; //默认在IntegerCache内(-128~127)可以相等,但超出cache会重新new一个
Integer i2 = Integer.valueOf(127);
System.out.println(i1 == i2);
System.out.println(i1.equals(i2));
  1. java异常分两类,一是可以通过代码恢复正常逻辑执行的异常,称为运行期异常: RuntimeException
    二是可以通过代码恢复正常逻辑执行的异常,称为编译期异常: Exception
    try{ 封装所有异常并抛出 }catch(抛出的异常对象 对象引用){ 异常的解决方案}catch(){ 捕捉多异常,先抓小范围}finally{最终执行的代码逻辑}
    如果方法中可能会出现问题,需要提前使用throws声明可能的异常;如果程序中需要手动抛出异常对象,那么需要使用throw关键字,然后new出新的(自定义)异常对象
    ===========================================================================================

以下属于进阶语法

  1. 不确定的有关系的数据进行相同的逻辑处理的场合,使用集合是一个不错的选择
    1.单一数据体系:Collection接口定义了相关的规则
    2.成对数据体系:Map接口定义了相关的规则,2个数据有关系,即键值对
    1.Collection接口
    常用接口
    List : 按照插入顺序保存数据,数据可重复
    具体实现类:ArrayList ,LinedList
    Set: 集,无序保存,数据不能重复
    具体实现类:HashSet
    Queue: 队列
    具体实现类:ArrayBlockingQueue
    2.Map接口
    具体实现类: HashMap Hashtable
  2. ArrayList = Array + List : 列表,清单 按照数据插入顺序进行存储; 集合内部按照数组进行存储
//ArrayList = Array + List : 列表,清单 按照数据插入顺序进行存储; 集合内部按照数组进行存储
ArrayList list = new ArrayList(2);  //放小括号里ctrl+P提示创建方式 有三种 传递整形参数,不传参,传集合参数
//    (1)传递整形参数:传int 用于设定底层数组长度
//    (2)不传参: 直接new 底层数组为空数组
//    (3)传集合参数: 传一个Collection集合类型的值,用于将其他集合中数据放在当前集合
list.add("zhangsan");
list.add(1,"lisi");//可以当插入用
list.add("zhangsan"); //自动扩容
System.out.println(list.get(2));
int i = 0;
while (i<list.size())
    i++;
//TODO 修改数据 将指定位置的数据使用set方法修改,传递两个参数,一是表数据位置,二是修改的值,会返回修改前的值
Object modify = list.set(2,"wangwu");
System.out.println("修改前value "+modify);
//TODO 删除数据 传参1个
Object remove = list.remove(2);
System.out.println("删除的值:"+remove);
ArrayList arrayList = new ArrayList();
arrayList.add("1"); arrayList.add("1");
list.clear();
list.addAll(arrayList);
//TODO 循环遍历不关心集合数据的位置,可采用特殊for循环
// for(循环对象:集合)
for (Object obj: list){
    
    
    System.out.println(obj);
}
//        list.clear(); //删除全部
list.removeAll(arrayList); //删除指定集合所有数据
System.out.println(list.contains("zhangsan")+" "+list.indexOf("zhangsan")); //数据不存在返回-1,存在返回第一个
System.out.println(list.isEmpty());
list.toArray();
Object clone = list.clone(); ArrayList list1 = (ArrayList) clone; //复制新集合
  1. LinkedList = Linked(连接) + List
    增加第一条数据,以及超出阈值时,LindedList快于ArrayList
    增加非第一条数据,且不超出阈值时,ArrayList快
    有索引时,ArrayList查找快;无索引时二者速度一致

    在这里插入图片描述
LinkedList list = new LinkedList();
list.add("zs");
list.addFirst("ls");// == list.push("ls");
list.add(1,"ww");
list.set(1,"www"); // list.addAll(otherList); list.contains("ls");
list.remove("www"); list.remove();//默认删除第一个==list.pop(); list.remove(1);list.removeLast(); 
System.out.println(list.get(0)+" "+list.getLast());
System.out.println(list.element()); //获取第一个数据 list.lastIndexOf();
list.clear();
  1. 泛型 : 类似于多态对声明对象所能使用的方法进行限制。例如学生集合只能存放学生对象,不能放老师对象。约束存放在集合里的数据类型,取得时候就不是Object类,也不用强制类型转换了。
    用于约束外部对象得使用场景叫做类型
    用于约束内部对象得使用场景叫做泛型 可传参时定义类型参数
 //泛型时规划内部的,可称之为类型参数
 MyContainer<User07> myContainer = new MyContainer();
//        myContainer.data = new Object(); //只能new User07
test(myContainer);//这会报错,因为泛型没有多态的用法,不能把父类的泛型 限制子类
public static void test(MyContainer<Object> myContainer){
    
    
 System.out.println(myContainer);
}
  1. HashSet:第一个放进去不一定第一个取出来,无序但有确定的Hash计算,由于哈希冲突所以不会重复存放数据(除非链地址法)

在这里插入图片描述
在这里插入图片描述
31. Queue
ArrayBlockingQueue = Array Blocking (阻塞,堵住) + Queue

ArrayBlockingQueue queue = new ArrayBlockingQueue(3);
queue.add("ww"); queue.put("ls"); boolean t1 = queue.offer("zs");
queue.poll(); queue.take();

添加数据 add:超过3会报错Queue full;put:多了会阻塞一直运行; offer是比较好的方法,加超过阈值不会再增加也不报错
取数据 poll:取多了会取null值; take:取多了会一直等待
其余方法 如isEmpty等也存在
32. HashMap **
HashMap 为了解决查找慢的问题,提供了
红黑二叉树**
在这里插入图片描述

//面向kv键值对,实现Map接口,底层也是数组+链表的hashset map版
HashMap<String, String> HashMap = new HashMap<>();
//添加修改均用put,会根据相同key,覆盖value
HashMap.put("zs","1");  HashMap.put("ls","1"); HashMap.put("ww","2");
System.out.println(HashMap.put("zs","3")); //覆盖的同时可以获得旧的值,如果是第一次put 返回值为null
System.out.println(HashMap.get("zs")+"\t"+HashMap);
HashMap.remove("zs");  HashMap.remove("ls","222");//第二个必须kv都相等才能删
HashMap.putIfAbsent("ww","4"); //有就添加,没就啥都不做
HashMap.replace("ww","4"); //真正的替换,没有该key值就返回null
Set set = HashMap.keySet();
Collection<String> values = HashMap.values();
System.out.println(set+":"+values);
HashMap.containsKey("ls");  HashMap.containsKey("1");
Set<Map.Entry<String, String>> entries = HashMap.entrySet();
for (Map.Entry<String, String> entry : entries) {
    
    
    System.out.println(entry); //entry.getKey();entry.getValue()
}
  1. Hashtable 同步:安全,Hashmap异步快
    在这里插入图片描述
//TODO 迭代器 获取在遍历时增加删除的数据,用for循环时只能修改数据,或者最后一次遍历时增删之前的数据   否则报错
        Iterator<String> iterator = keys.iterator();
        while (iterator.hasNext()) {
    
     //用于判断是否存在下一条数据
            String key = iterator.next();
            if(key.equals("b"))
                iterator.remove(); //限定只能删除此时的key value
            System.out.println(map.get(key));
        }
  1. 集合框架工具类和常见问题
    在这里插入图片描述
  2. File文件IO操作 与 其序列化(编码)
    在这里插入图片描述
//Unicode编码  组合过程叫做转码
// byte => -128~127  通过多个大于127的数字来组合表示中韩日文等:需要多个byte
// ascii => 0~127 常用字符  可用1个byte表示
public class IO02_Character {
    
    
//因此 改变数据的值不能直接在读取的data中修改
//简单可以用StringBuilder对象进行追加  =>   由此推出了字节流对字符串进行操作
public static void main(String[] args)  {
    
    
    String filePath = "G:\\project\\AAA\\run.sh";
    String filePath1 = "G:\\project\\backup\\sh.copy"; //自动生成sh.copy
    File file = new File(filePath);
    File desfile = new File(filePath1);

    BufferedReader reader = null; //字节输入流;
    PrintWriter writer = null; //字节输出流

    StringBuilder ss = new StringBuilder();
    try {
    
    
        reader = new BufferedReader(new FileReader(file)); //需要传一个FileReader对象
        writer = new PrintWriter(desfile);

        String line = null;//读取文件中一行数据(字符串)
            while((line=reader.readLine()) != null) {
    
    
                writer.println(line); //写入每一行
//                    ss.append((char)data);
            }
            writer.flush(); //刷写数据  =>  没装满也写入
//            ss.append(" zhangsan");//之后将字符串数组转化为字节数组,再将数组中每一个字节写入到文件中
    }catch (IOException e) {
    
     //可能会找不到该文件路径,因此放在try catch里
        throw new RuntimeException(e);
    }  finally {
    
    
            if (reader!=null){
    
    
                try {
    
    
                    reader.close();
                } catch (IOException e) {
    
    
                    throw new RuntimeException(e);
                }
            }if (writer!=null){
    
    
                    writer.close();
            }
        }
}
}

在Stream流中增加一个Buffer缓冲区
在这里插入图片描述
对象=>字节码文件(class) 序列化;反之则是反序列化

public class IO03_Object {
    
    
//序列化 & 反序列化  ; Object  =》  byte文件
public static void main(String[] args)  {
    
    
    String filePath = "G:\\project\\AAA\\outObject.txt";
    File file = new File(filePath);
    boolean isWrite = false;

    ObjectOutputStream objectOut = null; //对象输出流;
    FileOutputStream out = null; //文件输出流

    ObjectInputStream objectIn = null; //对象输入流;
    FileInputStream in = null;
    try {
    
    
        User33 user = new User33();
        if (isWrite){
    
    
            out = new FileOutputStream(file);
            objectOut = new ObjectOutputStream(out); //将Object写入到out的文件中
            //Java中只有增加了特殊标记:接口,才能在写文件的时候自动序列化
            objectOut.writeObject(user);
            objectOut.flush();
        }else {
    
    
            in = new FileInputStream(file);
            objectIn = new ObjectInputStream(in);
            Object o = objectIn.readObject();
            System.out.println((User33)o); //打印读取的对象
        }

    }catch (Exception e) {
    
     //可能会找不到该文件路径,因此放在try catch里
        throw new RuntimeException(e);
    }  finally {
    
    
            if (objectOut!=null){
    
    
                try {
    
    
                    objectOut.close();
                } catch (IOException e) {
    
    
                    throw new RuntimeException(e);
                }
            }if (out!=null){
    
    
                try {
    
    
                    out.close();
                } catch (IOException e) {
    
    
                    throw new RuntimeException(e);
                }
            }
        }
}
}
class User33 implements Serializable{
    
    
}

IO常见异常使用Try Catch: FileNotFoundException(new FileInputStream)
IOException(in.read/close)
ClassNotFoundException(objIn.readObject)
NotSerializableException(objOut.writeObject)
35. 线程运行
在这里插入图片描述
36. 线程池

//线程池:线程对象的容器,在启动时可创建1至多个线程对象
//Java常见线程池有4钟
//(1)创建固定数量的线程对象
ExecutorService executorService1 = Executors.newFixedThreadPool(3);
//(2)根据需求数量动态创建线程;不够就创建新的,但旧有的做完了也会拿来用
ExecutorService executorService2 = Executors.newCachedThreadPool();
//(3) 单一线程 如果某个工作需要按顺序可以用
ExecutorService executorService3 = Executors.newSingleThreadExecutor();
//(4)定时调度线程:DelayedWorkQueue
ExecutorService executorService4 = Executors.newScheduledThreadPool(3);

for(int i = 0; i<5;i++){
    
    
    executorService4.submit(new Runnable() {
    
    
        @Override
        public void run() {
    
    
            System.out.println(Thread.currentThread().getName());
        }
    });
}
  1. 线程同步
    在这里插入图片描述

  2. 线程安全
    在这里插入图片描述
    所谓的线程安全问题,其实是在多线程并发执行时,修改了共享内存中共享对象的属性,导致的数据冲突(类似脏读)
    在这里插入图片描述

  3. 反射基本操作
    多态中父类无法调用子类的方法因此Parent par = New Child();时,会限制调用Child类的方法。
    此时如果非要调用Child类的方法,需要借助反射 查看"镜中的自己"

Class<? extends User001> aClass = user.getClass();//类对象,对应Java中的Class文件

在cmd中输入以下命令,可查看字节码文件

javap -v Child(class名)
public class Reflect01_Class {
    
    
    public static void main(String[] args) throws Exception{
    
    
        User001 user = new Child001();
        user.test1();
//        user.test2();
        Class<? extends User001> aClass = user.getClass();//类对象,对应Java中的Class文件
        System.out.println(aClass.getSimpleName()); //获取类的名称 aClass.getPackageName()
        aClass.getName(); //获取类的全名:包括包名
        Class<?> superclass = aClass.getSuperclass(); //获取父类
        System.out.println(superclass);
        Class<?>[] interfaces = aClass.getInterfaces();//获取接口数组(可能多个)
        //TODO 获取类的属性
        Field f1 = aClass.getField("xxxx"); //根据属性名字获取类的public属性
        Field f2 = aClass.getDeclaredField("xxxx"); //所有权限,包括private
        Field[] declaredFields = aClass.getDeclaredFields(); //获取所有权限的所有属性
        Field[] Fields = aClass.getFields(); //public也相同
        //TODO 获取类的方法
        Method m1 = aClass.getMethod("test2");
        Method m2 = aClass.getDeclaredMethod("test1");
        Method[] Methods = aClass.getMethods();
        Method[] declaredMethods = aClass.getDeclaredMethods(); //同上
        //TODO 构造方法
        Constructor<? extends User001> constructor = aClass.getConstructor();
        Constructor<?>[] constructors = aClass.getConstructors();
        aClass.getDeclaredConstructor();
        //TODO 获取权限(修饰符public等):方法权限,类权限,等:多个修饰符合成一个int
        int modifiers = aClass.getModifiers();
        boolean aPrivate = Modifier.isPrivate(modifiers);//通过布尔值判断,其余也一样

    }
}
class User001{
    
    
    public void test1(){
    
    
        System.out.println("test1...");
    }
}
class Child001 extends  User001{
    
    
    public void test2(){
    
    
        System.out.println("test2...");
    }
}
  1. 反射类加载器
public class Reflect02_ClassLoader {
    
    
    public static void main(String[] args) {
    
    
        //Java类分为3钟  同理,类加载器也分3钟
        //1.Java核心类库中的类:String,Object
        //2. JVM 软件平台开发商 (java -version可以看到 Java HotSpot)
        //3. 自己写的类 User, Childer
        //(1)BootClassLoader:启动类加载器:Java核心类库
        //(2)PlatformClassLoader:平台类加载器  JVM平台等
         //(3)AppClassLoader:应用类加载器; (1)>(2)>(3)
        //TODO 获取类的信息
        Class<Student> studentClass = Student.class;
        ClassLoader classLoader = studentClass.getClassLoader();
        System.out.println(classLoader);//获取类的加载器信息 App
        System.out.println(classLoader.getParent());//获取平台类加载器信息
        System.out.println(classLoader.getParent().getParent());//获取启动类加载器

        Class<String> stringClass = String.class;
        System.out.println(stringClass.getClassLoader()); //null,因为启动类加载器是通过os平台实现,而不是java实现,不然会有前后冲突
    }
}
class Student{
    
    
}

练习以及常见异常

public class Reflect03_Test {
    
    
    public static void main(String[] args) throws Exception {
    
    
        //TODO 反射 练习 员工登录 与 常见异常
        //1.ClassNotFoundException  构建方法对象  第三种方法会导致没有类异常
        //2.NoSuchMethodException    没有方法异常<=getDeclaredConstructor
        //3.IllegalArgumentException    参数传递异常<=newInstance
        //4.NoSuchFieldException    没有属性异常<=getField
        //5.IllegalAccessException    权限异常 没权限还访问<=set
        //6.InvocationTargetException    调用目标异常 <=invoke
        //构建方法对象
        Class<Emp3> emp3Class = Emp3.class; //不new,采用反射构建方法对象
        Class<? extends Emp3> emp3Class2 = new Emp3().getClass(); //第二种方法
        Class<?> emp3Class3 = Class.forName("src.chapter05.Emp3");//或者采用全路径构建方法对象

        Constructor<Emp3> declaredConstructor = emp3Class.getDeclaredConstructor();
        //构建对象
        Emp3 emp3 = declaredConstructor.newInstance();
        //构建属性并赋值
        Field account = emp3Class.getField("account");
        Field password = emp3Class.getField("password");
        account.set(emp3,"zhangsan");
        password.set(emp3,"luoxiang");
        //获取登录方法并调用
        Method login = emp3Class.getMethod("login");
        Object result = login.invoke(emp3);//调用方法并接收结果
        System.out.println(result);

    }
}
class Emp3{
    
    
    public String account;
    public String password;
    public boolean login(){
    
    
        if("admin".equals(account) && "admin".equals(password))
            return true;
        else
            return false;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_42455006/article/details/129177527