反射【反射机制、Class类、Class应用】

第二十三章、反射

补充动态语言和静态语言区别

1、反射机制

image-20221230195449148

1.1java反射机制示意图

image-20230101115659258

image-20230102111036002

1.2、Java反射机制可以完成

1、在运行时判断任意一个对象所属的类

2、在运行时构造(创建)任意一个类的对象

3、在运行时得到任意一个类所具有的成员变量和方法

4、在运行时调用任意一个对象的成员变量和方法

5、生成动态代理

1.2、java反射的优缺点

image-20230102111312839

1.3、反射相关的主要类

image-20230101120545680

2、Class类

2.1、介绍

image-20230102112506717

2.2、Class类的常用方法

image-20230102112619433

2.3、获取Class的实例

1、内容

image-20230102115018495

2、例子

package reflection;

public class Test03 {
    public static void main(String [] args) throws ClassNotFoundException {
        Persion persion = new Student();
        System.out.println("这个人是:"+persion.name);

//        方式一通过对象获得
        Class c1 = persion.getClass();
        System.out.println(c1.hashCode());
//        方式二froname获得
        Class c2  = Class.forName("reflection.Student");
        System.out.println(c2.hashCode());
//        方式三、通过类名.class获得
        Class c3 = Student.class;
        System.out.println(c3.hashCode());

//        获取父类类型
        Class c4 = c1.getSuperclass();
        System.out.println(c4);
//        基本内置类型都会有一个
        Class [] c5 =c1.getInterfaces();
        System.out.println(c5);
    }
}
class Persion{
    public String name;
    public int age;    
}
class Student extends Persion {
    public Student() {
        this.name = "我是个学生";
    }
}
class Teacher extends Persion{
    public Teacher() {
        this.name ="我是个老师";
    }
}

2.4、哪些类型可以有Class对象

1、内容

image-20230102115351368

2、例子

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

        System.out.println(c1);
        System.out.println(c2);
        System.out.println(c3);
        System.out.println(c4);
        System.out.println(c5);
        System.out.println(c6);
        System.out.println(c7);
        System.out.println(c8);
        System.out.println(c9);
//只要元素类型与维度一样,就是同一个class
        int [] a = new  int [10];
        int [] b = new int [10000];
        System.out.println(a.getClass().hashCode());
        System.out.println(b.getClass().hashCode());
结果
    /**
class java.lang.Object
interface java.lang.Comparable
class [Ljava.lang.String;
class [[I
interface java.lang.Override
class java.lang.annotation.ElementType
class java.lang.Integer
void
class java.lang.Class
366712642
366712642 *//

2.5、java中内存分析

1、图解

image-20230102120725147

2、类加载的过程

image-20230102121110277

3、类的加载与ClassLoaderd的理解

image-20230102121222798

4、什么时候会发生类的初始化

image-20230103193133577

2.6、类加载器

1、作用

image-20230103200459619

2、类加载器的个数

image-20230103201948315

2.7、获取运行时类的完整形式

package reflection;

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

public class Test08 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
//        获取类的名字
        Class c1 = Class.forName("reflection.User");
        System.out.println(c1.getName());
        System.out.println(c1.getSimpleName());

//        获取类的属性
        Field[] fields = c1.getFields();//只能找到公共的类public

        fields = c1.getDeclaredFields();//找到全部的属性
        for (Field field:fields) {
            System.out.println(field);

        }

//        获取指定属性的值
        Field name = c1.getDeclaredField("name");
        System.out.println(name);

//        获取类的方法
        System.out.println("================");
        Method [] methods = c1.getMethods();//获取所有类的方法
        for (Method method : methods) {
            System.out.println("正常的:"+method);
        }
        methods = c1.getDeclaredMethods();//获得本类的所有方法
        for (Method method : methods) {
            System.out.println("DeclaredMethods:"+method);
        }

//        获取指定属性的值
        Field name1 = c1.getDeclaredField("name");
        System.out.println(name);

//        获取类的指定方法
        System.out.println("================");
        Method getName = c1.getMethod("getName",null);
        Method setName = c1.getMethod("setName", String.class);
        System.out.println(getName);
        System.out.println(setName);

//        获取全部构造器
        System.out.println("================");
        Constructor[] constructors = c1.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        constructors = c1.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            System.out.println("区分"+constructor);
        }

//        获取指定的构造器
        Constructor declaredConstructor = c1.getDeclaredConstructor(String.class,int.class,int.class);
        System.out.println("指定:"+declaredConstructor);

    }
}
/**
结果
"C:\Program Files\Java\jdk1.8.0_351\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2021.2\lib\idea_rt.jar=1904:C:\Program Files\JetBrains\IntelliJ IDEA 2021.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_351\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_351\jre\lib\rt.jar;C:\Users\qt\IdeaProjects\chapter21\out\production\chapter21" reflection.Test08
reflection.User
User
private java.lang.String reflection.User.name
private int reflection.User.id
private int reflection.User.age
private java.lang.String reflection.User.name
================
正常的:public java.lang.String reflection.User.getName()
正常的:public int reflection.User.getId()
正常的:public void reflection.User.setName(java.lang.String)
正常的:public void reflection.User.setId(int)
正常的:public void reflection.User.setAge(int)
正常的:public int reflection.User.getAge()
正常的:public final void java.lang.Object.wait() throws java.lang.InterruptedException
正常的:public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
正常的:public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
正常的:public boolean java.lang.Object.equals(java.lang.Object)
正常的:public java.lang.String java.lang.Object.toString()
正常的:public native int java.lang.Object.hashCode()
正常的:public final native java.lang.Class java.lang.Object.getClass()
正常的:public final native void java.lang.Object.notify()
正常的:public final native void java.lang.Object.notifyAll()
DeclaredMethods:public java.lang.String reflection.User.getName()
DeclaredMethods:public int reflection.User.getId()
DeclaredMethods:public void reflection.User.setName(java.lang.String)
DeclaredMethods:public void reflection.User.setId(int)
DeclaredMethods:public void reflection.User.setAge(int)
DeclaredMethods:public int reflection.User.getAge()
private java.lang.String reflection.User.name
================
public java.lang.String reflection.User.getName()
public void reflection.User.setName(java.lang.String)
================
public reflection.User(java.lang.String,int,int)
区分public reflection.User(java.lang.String,int,int)
指定:public reflection.User(java.lang.String,int,int)

Process finished with exit code 0
*//

3、class应用

3.1、有了class有啥用

1、作用

image-20230103214517821

3.2、调用指定的方法

image-20230103214641549

image-20230103214701307

3.3、setAccessible:安全访问机制

image-20230103214738476

3.4、反射实例(基础操作)

package reflection;

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

public class Test09 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
//        通过构造器创建对象
        Class c1 = Class.forName("reflection.User");
        Constructor constructor = c1.getDeclaredConstructor(String.class,int.class,int.class);
        User user2 = (User) constructor.newInstance("秦涛",001,18 );
        System.out.println(user2);
//        通过反射调用普通方法
        User user3 = (User) c1.newInstance();
//        通过反射获取一个方法
        Method setName = c1.getDeclaredMethod("setName",String.class);
//        invoke:是调用、激活的意思
        setName.invoke(user3,"秦涛");
        System.out.println(user3.getName());
        System.out.println("99999999999999999999999999999999999999999999999999999999");
//        通过反射操作属性
        User user4 = (User) c1.newInstance();
        Field name = c1.getDeclaredField("name");
        name.setAccessible(true);
        name.set(user4,"秦涛111111");
        System.out.println(user4.getName());

//

    }
}

3.5、反射性能对比

1、排行

1、普通方法>反射调用(关闭安全检测)>反射调用

2、例子

package reflection;

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

public class Test10 {

//    普通调用测试时间
    public static void test01(){
        User user = new User();

        long startTime = System.currentTimeMillis();
        for(int i =0;i<1000000000;i++){
            user.getName();
        }
        long endTime  = System.currentTimeMillis();
        System.out.println("普通方法调用跑了:"+(endTime-startTime)+"ms");

    }

//    反射进行方法调用测试时间
    public static void test02() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        Class c1 = user.getClass();
        Method getName =  c1.getDeclaredMethod("getName",null);

        long startTime = System.currentTimeMillis();
        for(int i =0;i<1000000000;i++){
            getName.invoke(user,null);
        }
        long endTime  = System.currentTimeMillis();
        System.out.println("反射方法调用对象跑了:"+(endTime-startTime)+"ms");

    }
    //反射关闭安全检测进行测试时间
    public static void test03() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        User user = new User();
        Class c1 = user.getClass();
        Method getName =  c1.getDeclaredMethod("getName",null);
        getName.setAccessible(true);
        long startTime = System.currentTimeMillis();
        for(int i =0;i<1000000000;i++){
            getName.invoke(user,null);
        }
        long endTime  = System.currentTimeMillis();
        System.out.println("反射关闭安全检测调用对象跑了:"+(endTime-startTime)+"ms");

    }

    public static void main(String[] args) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
        test01();
        test02();
        test03();
    }
}

3.6、反射操作泛型

1、作用、介绍

image-20230104200153555

2、例子

package 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 Test11 {

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

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

    public static void main(String[] args) throws NoSuchMethodException {
        Method method = Test11.class.getMethod("test01", Map.class,List.class);
        Type[]  genericParameterTypes = method.getGenericParameterTypes();
        for (Type genericParameterType : genericParameterTypes) {
            System.out.println("**:"+genericParameterType);
            if(genericParameterType instanceof ParameterizedType){  //进行判断genericParameterType是否为一个参数化类型
                Type[] autualTypeArguments = ((ParameterizedType)genericParameterType).getActualTypeArguments();//如果是,进行强转,调用getActualTypeArguments()方法获得真是获得真是的参数类型

                for (Type autualTypeArgument : autualTypeArguments) {
                    System.out.println(autualTypeArgument);
                }
            }
        }

        method = Test11.class.getMethod("test02",null);
        Type[]  genericParameterType1 = method.getGenericParameterTypes();
        for (Type genericParameterType : genericParameterType1) {
            System.out.println("**:"+genericParameterType);
            if(genericParameterType instanceof ParameterizedType){  //进行判断genericParameterType是否为一个参数化类型
                Type[] autualTypeArguments = ((ParameterizedType)genericParameterType).getActualTypeArguments();//如果是,进行强转,调用getActualTypeArguments()方法获得真是获得真是的参数类型

                for (Type autualTypeArgument : autualTypeArguments) {
                    System.out.println(autualTypeArgument);
                }
            }
        }
    }
}
/**
结果
**:java.util.Map<java.lang.String, reflection.User>
class java.lang.String
class reflection.User
**:java.util.List<reflection.User>
class reflection.User

Process finished with exit code 0

3.7、练习ORM

1、内容

image-20230104202749055

2、例子

package reflection;

import com.sun.istack.internal.Interned;

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

/**
 *
 * 反射操作注解
 */
public class Test12 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class c1 = Class.forName("reflection.Student2");

//        通过反射获得注解
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }

//        获取注解的value的值
        Tabletao tabletao = (Tabletao) c1.getAnnotation(Tabletao.class);
        String value = tabletao.value();
        System.out.println(value);

//        获取类指定的注解
        Field f = c1.getDeclaredField("age");
        Filetao annotation = f.getAnnotation(Filetao.class);
        System.out.println(annotation.colunName());
        System.out.println(annotation.type());
        System.out.println(annotation.length());

    }

}
@Tabletao("db_student")
class  Student2{
    @Filetao(colunName = "db_id",type = "int",length =10)
    private int id;
    @Filetao(colunName = "db_age",type = "int",length =8)
    private int age;
    @Filetao(colunName = "db_name",type = "int",length =5)
    private String name;

    public Student2() {
    }

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

    public int getId() {
        return id;
    }

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

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Student2{" +
                "id=" + id +
                ", age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

//类名的注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@interface Tabletao{
    String value();
}

//属性的注解
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface Filetao{
    String colunName();
    String type();
    int length();
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇