首先讲解何为反射:
例如外挂:在程序正在跑的时候 加入一段代码,就可以实现得到一些东西,那么这个就是HOOK钩子注入
其实外挂就是这个过程,例如,打开游戏的时候正在运行的时候,这个时候打开外挂,就可以用锁血什么的。这其实就有点类似于这个了,专业术语也叫做HOOK钩子
package org.example;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
public class Main {
//测试调用我们的MyAnnotation方法
@MyAnnotation
public void Test01(){
}
//测试元注解
//定义一个注解
//定于ElementType.METHOD 之后,那么就只能在方法上进行使用,其它的方法可以参考官方文档
@Target(value = ElementType.METHOD)
//@interface是定义一个接口的意思
@interface MyAnnotation{
}
}
如果是这样定义的话,那么就只能放在方法上
如果像写在类上的话,在target中可以定义新增一个参数,这样的话就可以在类中调用这个接口了
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention 表示我们的注解在什么地方还有效
@Target(value = {ElementType.METHOD,ElementType.TYPE})
@Retention(value = RetentionPolicy.RUNTIME)
@interface MyAnnotation{
}
Documented
表示是否将我们的注解声称在JAVAdoc中
Inherited
意思就是注解的子类可以继承父类的注解
annoutation
这里给他定义一个接口,叫做MyAnnotation
import javax.swing.text.Element;
import java.lang.annotation.*;
import java.util.ArrayList;
import java.util.List;
public class Main {
//这里定义了第一个注解MyAnnotation @interface只是一个接口而已
//这个要自定义注解,那么就要加上@Target 和 @ Retention
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{}
}
```然后添加一些元注解
```java
package org.kuang.annoutation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
public class Test01 {
@MyAnnotation(name = "小红") //调用注解
public class Test02{
}
}
//定义一个注解
//target中的参数的意思是 1、METHOD允许在方法上定义。2、TYPE允许在类上定义
@Target({ElementType.METHOD,ElementType.TYPE})
@interface MyAnnotation{
//注解的参数必须为:参数类型+参数名()
String name () default ""; //定义一个空的参数
}
可以多写一些参数,例如
@Target({ElementType.METHOD,ElementType.TYPE})
@interface MyAnnotation{
String name() default ""; //定义一个空的参数
int age() default 0;
int id() default -1; //如果默认代表为-1,那么则显示不存在
String[] schools() default {"清华","北大"};
}
default代表着默认值的意思,当我们定义为默认值之后,那么就可以不用进行传参,因为已经默认定好了值
import javax.swing.text.Element;
import java.lang.annotation.*;
import java.util.ArrayList;
import java.util.List;
public class Main {
//这里将会调用@MyAnnotation注解
@MyAnnotation(age = 1,name = "赵日天")
public void test(){
}
//这里定义了第一个注解MyAnnotation @interface只是一个接口而已
//这个要自定义注解,那么就要加上@Target 和 @ Retention
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
//注解中的参数要这样去定义: 参数类型 + 参数名();
String name() default ""; //如果调用MyAnnotation中的name不赋值的话,默认为空,default就是定义他为空的意思
int age();
int id() default -1;
String[] Schools() default {"西部牛仔","美国华盛顿职业技术学院"}; //这里变量列表定义了两个参数
}
}
```如果你想定义注解只有一个值的情况,可以这样编写
```java
@MyAnnotation1("李天龙")
public void test2(){
}
//如果你想定义注解只有一个值的情况,可以这样编写
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation1{
//如果只有一个参数的情况下,建议用value来命名
String value();
}
反射相关的主要API
java.lang.Class 代表一个类
java.lang.reflect.Method 代表一个类的方法
java.lang.reflect.Field 代表类的成员变量
java.lang.reflect.Constructor 代表类的构造器
首先我们先定义一个实体类,私有的
java类中的get 和set构造是什么意思?有什么用?什么场景下使用?
get和set是Java类中的两种常见方法,用于获取和设置类的属性值。get方法用于获取属性值,set方法用于设置属性值。
这两种方法的作用是为了保护类的属性,防止外部直接访问和修改类的属性值,从而保证类的封装性和安全性。同时,get和set方法也提供了一种方便的方式来访问和修改类的属性值。
在Java编程中,通常情况下,我们会将类的属性设置为私有的(private),这样外部就无法直接访问和修改属性值。而通过get和set方法,我们可以在类的内部控制属性的访问和修改,从而保证了类的封装性和安全性。
使用get和set方法的场景非常广泛,例如在Java Web开发中,我们通常会使用JavaBean来封装表单数据,这时就需要使用get和set方法来获取和设置表单数据的属性值。另外,在Java框架中,也经常使用get和set方法来操作数据库中的数据。
//什么叫反射
public class test1 {
}
//实体类
class User{
private String name;
private int id;
private int age;
//User类中的无参构造
public User() {
}
//User类中的有参构造
public User(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
//通常来说类的属性都是私有的,所以我们要设置get和set来进行封装
//我们可以在类的内部控制属性的访问和修改,从而保证了类的封装性和安全性。
public String getName() {
return name;
}
public void setName(String name) {
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;
}
//再加一个tostring,方便我们写程序时调试
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", id=" + id +
", age=" + age +
'}';
}
}
在main方法中进行调试
public class test03 {
public static void main(String[] args) throws ClassNotFoundException {
//通过反射获取class对象
Class c1 = Class.forName("org.kuang.annoutation.User");
System.out.println(c1);
}
}
得到一个Class结果
打印hashcode可以证明 都是一样的,来自同一份文件
package org.kuang.annoutation;
public class test03 {
public static void main(String[] args) throws ClassNotFoundException {
//通过反射获取class对象
Class c1 = Class.forName("org.kuang.annoutation.User");
Class c2 = Class.forName("org.kuang.annoutation.User");
Class c3 = Class.forName("org.kuang.annoutation.User");
Class c4 = Class.forName("org.kuang.annoutation.User");
System.out.println(c1.hashCode());
System.out.println(c2.hashCode());
System.out.println(c3.hashCode());
System.out.println(c4.hashCode());
}
}
//创建实体类
class User{
private String name;
private int id;
private int age;
//创建一个无参构造
public User() {
}
//创建一个有参构造
public User(String name, int id, int age) {
this.name = name;
this.id = id;
this.age = age;
}
//因为我们是private是私有的,所以我们还需要定义get/set
public String getName() {
return name;
}
public void setName(String name) {
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;
}
//再写一个tostring,方便我们调试
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", id=" + id +
", age=" + age +
'}';
}
}
通过反射之后,可以直接调用私有变量中的任何参数
定义一个类,其属性为私有的,定义有参和无参构造,然后定义get和set方法,来封装和保护方法。
到最后也反射调用方法获取方法
也是在main方法中使用Class.forname()函数
用户名 | 金币 | 积分 | 时间 | 理由 |
---|---|---|---|---|
Track-魔方 | 150.00 | 0 | 2023-06-07 14:02:07 | 一个受益终生的帖子~~ |
打赏我,让我更有动力~
© 2016 - 2024 掌控者 All Rights Reserved.
Track-魔方
发表于 2023-6-7
内容相对基础,期待有具体漏洞案例的内容产出
评论列表
加载数据中...
coteack888
发表于 2023-6-27
我的思念在火星流浪,超级大乐透 我的祝福在珠峰飘荡,我的牵挂在”神六”翱翔,我的依恋在南极冷藏,福彩七乐彩 我的体贴在五湖四海歌唱—无论你离我有多远,都无法逃避我用心绕下的情网。我的思念在火星流浪,我的祝福在珠峰飘荡,我的牵挂在”神六”翱翔,我的依恋在南极冷藏,波场时时彩 我的体贴在五湖四海歌唱—无论你离我有多远,都无法逃避我用心绕下的情网。
评论列表
加载数据中...