程序笔记   发布时间:2022-07-16  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了【小白学java】D34》》》类加载(器)& 反射 & 正则表达式大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

【小白学java】D34》》》类加载(器)& 反射 & 正则表达式


🧡💛💚💙Ὁc;🤎💗感谢各位一直以来的支持和鼓励🧡💛💚💙Ὁc;🤎💗 制作不易🙏🙏🙏求点赞👍 👍 👍 ɹ5; 收藏 ⭐ ⭐ ⭐ ɹ5;关注ɰ5;ɰ5;ɰ5; ▛▛▛▛▛▛▛▛▛▛▛▛▛▛▛▛▛▜▜▜▜▜▜▜▜▜▜▜▜▜▜▜▜▜▜ 👉👉👉👉👉👉🧡💛💚💙Ὁc;🤎💗 一键三连走起 🧡💛💚💙Ὁc;🤎💗


一、 了解类加载

(1 )概述:

        当程序要使用某个类时,如果该类还没有加载到内存中,系统会通过类的加载,类的连接,类的初始化三个步骤来对类进行初始化

(2)类的加载

  • 将class文件(源文件)读取内存,并创建对应的Class对象
  • 任何类被使用时,系统都会创建一个java.lang.Class对象

(3) 类的连接

  • 验证阶段:检验被加载的类和相关类(父类/接口)内部结构是否合法
  • 准备阶段:负责为类中的变量分配内存,并设置默认值
  • 解析阶段:将类的二进制数据中字符(方法)引用改为直接引用

(4)类的初始化:

        对类变量进行初始化(赋值)

  • 1.当类还未被加载和连接时࿰c;程序要先加载并连接该类
  • 2.该类的直接父类未被初始化࿰c;要先初始化直接父类
  • 3.假如类中有初始化语句(非static修饰)࿰c;那么依次执行初始化语句 执行步骤2时,同样遵循1-3

(5)类加载的使用

  • 创建类的实例
  • 操作类或相关的类变量
  • 调用类方法
  • 初始化子类
  • 直接使用java.exe运行某个主类
  • 使用反射方式强制创建类或接口对应的Class对象

二、类加载器

        Java加载类时,都是通过类加载器来进行加载

(1)类加载器的作用:

        负责将class文件加载到内存中࿰c;生成对应的Class对象

(2)类加载器的机制

  • 全盘负责:当类加载器负责加载某一个class文件时,与之相关的class文件也由该类加载器负责,除非显示由另一个加载器负责
  • 父类委托:加载某一个class文件时,先让父类的加载器试图加载该class文件,只有在父类无法加载该class文件时,才尝试从自己的类路径加载
  • 缓存机制:会把所有加载的class文件生成的Class对象进行缓存,当程序需要使用某一个Class对象时,类加载器首先去缓存中搜索,缓存中不存在时,才会将class文件加载到内存中,并生成对应的Class对象

三、反射

        反射就是在运行状态中࿰c;对于任意一个类࿰c;都能够知道这个类的所有属性和方法;对于任意一个对象࿰c;都能够调用它的任意方法和属性;并且能改变它的属性。这也就是Java被视为动态(或准动态)原因࿰c;为什么说是准动态࿰c;是因为一般而言的动态语言定义是程序运行时࿰c;允许改变程序结构或变量类型࿰c;这种语言称为动态语言。

(1) 反射获取Class对象

通过反射使用一个类,需要获取该类字节码文件,也就是类型为Class的对象

获取方式

  • 1.使用该类的class属性来获取对应的Class对象,
  • 2.调用该类的getClass()方法,返回该对象所属类对用的Class对象 该方法是Object中的方法,所有类都可以调动
  • 3.使用Class中的静态方法forName(String className),该方法需要传入String参数,参数是某个类完整的包名

示例代码:

//1.使用该类的class属性来获取对应的Class对象,
// 获取User类编译后的字节码文件 User.class
Class<User> userClass = User.class;
System.out.println(userClass);
//class com.xiaobei.lambda.demo_clasS.User 返回该类的路径(位置)

//2.调用getClass()方法,返回该对象所属类对用的Class对象
// getClass()方法是Object中的方法,所有类都可以调动,
User user = new User();//创建对象
Class<? extends User> userClass1 = user.getClass();
System.out.println(userClass1);
//class com.xiaobei.lambda.demo_clasS.User 返回该类的路径(位置)

// 3.使用Class中的静态方法forName(String className),
// 该方法需要传入String类型的参数,参数是某个类完整的包名
Class<?> aClass = Class.forName("com.xiaobei.lambda.demo_clasS.User");
System.out.println(aClass);

测试结果:

【小白学java】D34》》》类加载(器)& 反射 & 正则表达式

(2)反射获取构造方法

Class类中用于获取构造方法的方法:

Constructor<?>[] getConstructors():
			获取所有公共构造对象的数组
Constructor<?>[] getDeclaredConstructors():
			获取所有构造对象的数组
Constructor<T>[] getConstructors(Class<?>... parameterTypes):
			返回单个公共构造方法对象
Constructor<T>[] getDeclaredConstructor(Class<?>... parameterTypes):
			返回单个构造方法对象

Class类中用于使用构造方法的方法:

T newInstance(Object... initargs);
			根据指定的构造方法创建对象

注意: 通过反射私有化构造不能直接创建对象需要通过setAccessible方法

示例代码;

public class User {
    
    //无参构造
    public User() {
    System.out.println("我是无参构造");
    }

    //有参构造
    public User(String name) {
        System.out.println("我是有参构造t"+name);

    }
    //私有构造
    private  User(String name,int age){
        System.out.println("我是私有有参构造t"+name+"--"+age);
    }

}
public class Test {
    public static void @H_337_162@main(String[] args) throws NoSuchMethodException {
        // 获取User类编译后的字节码文件 User.class
        Class<User> userClass = User.class;
        //1. Constructor<?>[] getConstructors():获取所有公共构造对象的数组
        System.out.println("获取所有公共构造对象的数组");
        Constructor<?>[] userClassConstructors = userClass.getConstructors();
        for (Constructor<?> userClassConstructor : userClassConstructors) {
            System.out.println(userClassConstructor);
        }
        System.out.println("--------------------------------");

        //2.Constructor<?>[] getDeclaredConstructors():获取所有构造对象的数组
        System.out.println("获取所有构造对象的数组");
        Constructor<?>[] declaredConstructors = userClass.getDeclaredConstructors();
        for (Constructor<?> declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }
        System.out.println("--------------------------------");

        //3. Constructor<T>[] getConstructors(Class<?>... parameterTypes):返回单个公共构造方法对象
        System.out.println("返回单个公共构造方法对象");
        Constructor<User> constructor = userClass.getConstructor(String.class);
        System.out.println(constructor);
        System.out.println("--------------------------------");

        //4. Constructor<T>[] getDeclaredConstructor(Class<?>... parameterTypes):返回单个构造方法对象
        System.out.println("返回单个构造方法对象");
        Constructor<User> declaredConstructor = userClass.getDeclaredConstructor(String.class,int.class);
        System.out.println(declaredConstructor);
        Constructor<User> declaredConstructor1 = userClass.getDeclaredConstructor(String.class);
        System.out.println(declaredConstructor1);
        System.out.println("--------------------------------");
         

 //5. T newInstance(Object... initargs);根据指定的构造方法创建对象
        //每个类都有一个默认的构造方法࿰c;所以不需要指定࿰c;可以直接使用
        User user = userClass.newInstance();
        System.out.println(user);
        //使用指定构造方法创建对象
        Constructor<User> declaredConstructor2 = userClass.getDeclaredConstructor(String.class);
        User user1 = declaredConstructor2.newInstance("张三");
        System.out.println(user1);
        //使用指定私有方法创建对象
        //注意:会报错private 修饰的无妨创建
        //解决办法:因为编译过程中会检测是否符合Java语法格式࿰c;那么我们可以绕过编译安全检测机制(又称“暴力反射”/“暴射”)
        Constructor<User> declaredConstructor3 = userClass.getDeclaredConstructor(String.class, int.class);
        //设置为可通行的语法格式࿰c;可以让Class对象认为private修饰的构造符合
        declaredConstructor3.setAccessible(true);
        User user2 = declaredConstructor3.newInstance("李四", 20);
        System.out.println(user2);



    }
}

测试结果:

【小白学java】D34》》》类加载(器)& 反射 & 正则表达式

(3)反射获取成员变量方法

Class类中用与获取成员变量的方法

Field[] getFields();获取所有公共成员变量的数组
Field[] getDeclaredFields();获取所有成员变量的数组
Field[] getFields(String name);返回单个公共成员变量的对象
Field[] getDeclaredFields(String name);返回单个成员变量的对象

Class类中用与成员变量赋值的方法

void set(Object obj,Object value): 给obj对象的成员赋值value

注意:
	通过反射私有化成员不能直接赋值࿰c;需要通过setAccessible()方法

示例代码:

public class User {
    public String name;
    public int  uid;

    private int age;
    private  double weight;
}
public class Test {
    public static void @H_337_162@main(String[] args) throws Exception {
        // 获取User类编译后的字节码文件 User.class
        Class<User> userClass = User.class;
        //Class类中用与获取成员变量的方法
        //Field[] getFields();获取所有公共成员变量的数组
        System.out.println("获取所有公共成员变量的数组");
        Field[] fields = userClass.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("-----------------------------");

        //Field[] getDeclaredFields();获取所有成员变量的数组
        System.out.println("获取所有成员变量的数组");
        Field[] declaredFields = userClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        System.out.println("-----------------------------");

        //Field[] getFields(String Name);返回单个公共成员变量的对象
        System.out.println("返回单个公共成员变量的对象");
        Field field = userClass.getField("name");
        System.out.println(field);
        System.out.println("-----------------------------");

        //Field[] getDeclaredFields(String Name);返回单个成员变量的对象
        System.out.println("返回单个成员变量的对象");
        Field name = userClass.getDeclaredField("name");
        System.out.println(name);
        Field age = userClass.getDeclaredField("age");
        System.out.println(age);
        System.out.println("-----------------------------");

        //Class类中用与成员变量赋值的方法
        //void set(Object obj,Object value):给obj对象的成员赋值value
        //给公有的成员变量赋值
        System.out.println("给公有的成员变量赋值");
        Field name1 = userClass.getDeclaredField("name");
        User user = userClass.newInstance();
        name1.set(user,"张三");
        System.out.println(user.name);
        //给私有的成员变量赋值
        System.out.println("给私有的成员变量赋值");
        Field age1 = userClass.getDeclaredField("age");
        //绕过安全检测机制
        age1.setAccessible(true);
        User user1 = userClass.newInstance();
        age1.set(user1,20);
        //System.out.println(user1.agE);//不符合java语法
        Object o = age1.get(user1);
        System.out.println(o);
    }
}

测试结果:

【小白学java】D34》》》类加载(器)& 反射 & 正则表达式

(4)反射获取成员方法方法

Class类中用与获取成员变量的方法

@H_444_136@method[] getMethods();
		获取所有公共成员方法(包括继承)的数组
@H_444_136@method[] getDeclaredMethods();
		获取所有成员方法(不包括继承)的数组
@H_444_136@method[] getMethod(String name,Class<?>... parameterTypes);
		返回单个公共成员方法的对象
@H_444_136@method[] getDeclaredMethod(String name,Class<?>... parameterTypes);
		返回单个成员方法的对象

@H_455_13@method类中用与调用成员方法的方法

Object invoke(Object obj,Object...args):
		调用obj对象的成员方法参数为args,返回值为Object

注意:
	通过反射私有化成员方法不能直接调用࿰c;需要通过setAccessible方法

测试代码:

public class User {

    public void  fun(){
        System.out.println("我是公有无参成员方法");
    }
    public void  show(int sum){
        System.out.println("我是公有有参成员方法"+ sum);
    }

    private void  fun1(){
        System.out.println("我是私有无参成员方法");
    }
    private void  show1(int sum){
        System.out.println("我是私有有参成员方法"+ sum);
    }

}

public class Test {
    public static void @H_337_162@main(String[] args) throws Exception {
        // 获取User类编译后的字节码文件 User.class
        Class<User> userClass = User.class;

        //Class类中用与获取成员变量的方法
        //Method[] getMethods();获取所有公共成员方法(包括继承)的数组
        System.out.println("获取所有公共成员方法(包括继承)的数组");
        @H_444_136@method[] methods = userClass.getMethods();
        for (@H_444_136@method method : methods) {
            System.out.println(@H_154_133@method);
        }
        System.out.println("----------------------------------");

        //Method[] getDeclaredMethods();获取所有成员方法(不包括继承)的数组
        System.out.println("获取所有成员方法(不包括继承)的数组");
        @H_444_136@method[] declaredMethods = userClass.getDeclaredMethods();
        for (@H_444_136@method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        System.out.println("----------------------------------");

        //Method[] getMethod(String name,Class<?>... parameterTypes);返回单个公共成员方法的对象
        System.out.println("返回单个公共成员方法的对象");
        @H_444_136@method show = userClass.getMethod("fun");
        System.out.println(show);
        System.out.println("----------------------------------");

        //Method[] getDeclaredMethods(String name,Class<?>... parameterTypes);返回单个成员方法的对象
        System.out.println("返回单个成员方法的对象");
        //公有
        @H_444_136@method show1 = userClass.getDeclaredMethod("show", int.class);
        System.out.println(show1);
        //私有
        @H_444_136@method show11 = userClass.getDeclaredMethod("show1", int.class);
        System.out.println(show11);
        System.out.println("----------------------------------");


        //Method类中用与调用成员方法的方法
        //Object invoke(Object obj,Object...args):
        // 调用obj对象的成员方法参数为args,返回值为Object
        //公有
        @H_444_136@method show12 = userClass.getDeclaredMethod("fun");
        User user = userClass.newInstance();
        show12.invoke(user);
        //私有
        @H_444_136@method show13 = userClass.getDeclaredMethod("show1", int.class);
        show13.setAccessible(true);//绕过类型检测机制
        User user1 = userClass.newInstance();
        show13.invoke(user1,30);

    }
}

测试结果:

【小白学java】D34》》》类加载(器)& 反射 & 正则表达式

【小白学java】D34》》》类加载(器)& 反射 & 正则表达式

四、正则表达式

正则表达式的作用

        使用简洁的代码࿰c;严谨的验证文本框中的内容

正则表达式的模式

  • 简单模式:只能表示具体的匹配
  • 复合模式:可以使用通配符表达更为抽象的规则模式

正则表达式符号

符号功能描述
匹配的内容
/…/表示一个模式的开始和结束
^表示匹配字符串的开始
$表示匹配字符串的结束
s表示任何的空白字符
S表示任何的非空白字符
d表示匹配一个数字字符࿰c;等价于[0-9]
D表示除了数字之外的任何字符࿰c;等价于[^0-9]
w表示匹配一个数字、下划线或字母字符࿰c;等价于[A-Za-z0-9_ ]
W表示任何非单字字符࿰c;等价于[^a-zA-z0-9_ ]
.表示除了换行符之外的任意字符
[a-z]表示匹配a到z之间的任意字符
匹配的次数
{n}表示匹配前一项n次
{n,}表示匹配前一项n次࿰c;或者多次
{n,m}表示匹配前一项至少n次࿰c;但是不能超过m次
*表示 匹配前一项0次或多次࿰c;等价于{0,}
+表示匹配前一项1次或多次࿰c;等价于{1,}
表示匹配前一项0次或1次࿰c;也就是说前一项是可选的࿰c;等价于{0,1}

正则表达式的功能

	匹配:	matches
	切割:	split
	替换:	replaceAll
	获取:	find、group

正则表达式的使用

【案例一】:判断QQ号是否合法

import java.util.regex.@H_444_136@matcher;
import java.util.regex.Pattern;

public class Task {
    public static void @H_337_162@main(String[] args) {
        //判断QQ号(5-10位)是否合法࿰c;例如:12345678(5-8位数字)
        String  qq="2601149032";
        //写正则表达式
        String reg="^[1-9]{5,9}$";
        //转换String->Reg
        //使用Pattern类compile()方法
        Pattern compile = Pattern.compile(reg);
        //匹配,调用Matcher类的matcher()方法࿰c;匹配判断是否合法
        @H_444_136@matcher matcher = compile.@H_337_162@matcher(qq);
        //调用find()方法࿰c;判断匹配是否合法
        Boolean b = matcher.find();
        System.out.println(b);//返回true,合法
    }
}

【案例二】:判断手机号是否合法

public class Task {
    public static void @H_337_162@main(String[] args) {
		//判断手机号(1开头࿰c;11位数)是否合法
        String  qq="13850536081";
        //写正则表达式
        String reg="^1[0-9]{10}$";
        //转换String->Reg
        //使用Pattern类compile()方法
        Pattern compile = Pattern.compile(reg);
        //匹配,调用Matcher类的matcher()方法࿰c;匹配判断是否合法
        @H_444_136@matcher matcher = compile.@H_337_162@matcher(qq);
        //调用find()方法࿰c;判断匹配是否合法
        Boolean b = matcher.find();
        System.out.println(b);//true,合法
   }
}

【案例三】:判断QQEmail是否合法

public class Task {
    public static void @H_337_162@main(String[] args) {
		//验证QQ邮箱是否合法(0不能开头࿰c;6-10位数字࿰c;后缀 @qq.com)
        String qqemail="123ab67891@qq.com";
        String reg ="^[1-9][0-9]{5,9}@qq.com$";
        Pattern compile = Pattern.compile(reg);
        @H_444_136@matcher matcher = compile.@H_337_162@matcher(qqemail);
        Boolean b = matcher.find();
        System.out.println(b);//返回false࿰c;不合法
   }
}

【案例四】:判断邮箱的格式是否正确

以123ab67891@qq.com和a1236548@163.com为例演示

public class Task {
    public static void @H_337_162@main(String[] args) {
		//验证邮箱格式是否合法(10位数字࿰c;后缀 @qq.com或则@163.com)
        //QQ邮箱࿰c;(0不能开头࿰c;6-10位数字࿰c;后缀 @qq.com)
        String qqemail="123ab67891@qq.com";
        //网易邮箱࿰c;允许有一个字母5-11个数字@163.com
        String wyemail="a1236548@163.com";

        //String reg ="^(([1-9][0-9]{5,9}@qq.com)|([A-z][0-9]{5,11}@163.com))$";
        String reg ="^([1-9][0-9]{5,9}@qq)|([A-z][0-9]{5,11}@163).com$";
        Pattern compile = Pattern.compile(reg);

        @H_444_136@matcher matcher = compile.@H_337_162@matcher(qqemail);
        Boolean b = matcher.find();
        System.out.println(b);//返回false࿰c;不合法

        @H_444_136@matcher matcher1 = compile.@H_337_162@matcher(wyemail);
        Boolean b1 = matcher1.find();
        System.out.println(b1);//返回true,合法
   }
}

大佬总结

以上是大佬教程为你收集整理的【小白学java】D34》》》类加载(器)& 反射 & 正则表达式全部内容,希望文章能够帮你解决【小白学java】D34》》》类加载(器)& 反射 & 正则表达式所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。