有关对这个字节码文件的理解,以及如何去使用(字段内容的获取设置内容,方法的获取以及调用,构造方法的获取以及调用)

一.读取字节码文件的三种方式

package com.project.Reflect;

import java.util.Date;

/**
 * 获取字节码文件的第一种方式
 */
public class ReflectDemo1 {
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//		System.out.println("你好");
		Class<?> aClass = Class.forName("java.lang.String");
		System.out.println(aClass);
//		System.out.println(aClass.newInstance());
		Class<?> aClass1 = Class.forName("java.util.Date");
		System.out.println(aClass1);
		Class<?> aClass2 = Class.forName("java.lang.Integer");
		System.out.println(aClass2);
		
		
		//java当中任何一个对像都有一个方法getClass
		String s="asd";
		Class<? extends String> aClass3 = s.getClass();
		System.out.println(aClass3==aClass);
		Date time=new Date();
//		System.out.println(time.getTime());
		System.out.println(time.getClass());
		
		//第三中当时获取字节码文件java语言当中任何一个类型都会有这个class属性
		Class<String> stringClass = String.class;
		Class<Date> dateClass = Date.class;
		Class<Integer> integerClass = int.class;
		Class<Double> doubleClass = double.class;
		System.out.println(stringClass);
	}
}

二.通过反射机制来创建一个对象

package com.project.Reflect;

import com.project.bean.User;

public class ReflectDemo2 {
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		User user = new User();
//		System.out.println(user);
		
		//本质上这个就i是调用了这个无参数的构造方法
		//后面还有这个有参数的构造方法
		//通过这个class来实例化对象
		//通过反射机制来创建对象
		Class<User> aClass = (Class<User>) Class.forName("com.project.bean.User");
		User user1 = aClass.newInstance();
		//这个行会调用他的无参数的构造方法!!
		//com.project.bean.User@3b07d329
		System.out.println(user1);
	}

四.把这个字节码的类名写在这个properties文件中如何去读取

package com.project.Reflect;

import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

/**
 * 验证反射机制的灵活性
 * java 代码写一遍就可以实现不同对象的实例化
 */
public class ReflectDemo3 {
	public static void main(String[] args) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
	   //通过io流读取这个文件
		//E:\springProject\javaStudyClass
		FileReader reader=new FileReader("Classinfo.properties");
		Properties properties = new Properties();
		
		//加载properties
		properties.load(reader);
		
		//关闭流
		reader.close();
		
		String className = properties.getProperty("ClassName");
		System.out.println(className);
		Class<?> aClass =  Class.forName(className);
		Object o = aClass.newInstance();
		System.out.println(o.toString());
	}
}

五.获取这个字节码文件当中的字段属性

package com.project.Reflect;

import com.project.bean.Student;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;

//反射与一下属性


/**
 * getFields   获取公开的属性名  就是使用这个public进行修饰的内容这个
 *
 */
public class ReflectDemo5 {
	public static void main(String[] args) {
	   //获取类
		try {
			Class<?> aClass = Class.forName("com.project.bean.Student");
//			Class<? extends Class> aClass1 = aClass.getClass();
			System.out.println(aClass.getSimpleName());
			//获取一个简类名
			//获取到的是一个public修饰的
//			Field[] fields = aClass.getFields();
//			Arrays.stream(fields).forEac
//			h(field -> {
//				System.out.println(field.getName());
//			});
			
			//获取到的是所有的字段元素
			Field[] fields = aClass.getDeclaredFields();
			Arrays.stream(fields).forEach(field -> {
//				System.out.println(field.getName());
				//获取属性的名字
				//获取到这个简单的类型的名称
//				System.out.println(field.getType().getSimpleName());
//				System.out.println(field.getType().getName());
				//获取属性的简名称
//				System.out.println(field.getGenericType());
//				获取修饰符的属性列表
				int modifiers = field.getModifiers();
//				System.out.println(modifiers);
				System.out.println(Modifier.toString(modifiers));
			});
		} catch (ClassNotFoundException e) {
			throw new RuntimeException(e);
		}
	}
}

六.通过这个反射机制给这个属性进行赋值并且完整的把这个类给拼接出来(自己设置一个类直接把这个类名修改尝试即可)

package com.project.Reflect;

import com.project.bean.Student;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Arrays;

/**
 * //		Class<Student> studentClass = Student.class;
 * //		System.out.println(studentClass);
 *  //		System.out.println(new Student().getClass());
// *  不是用这个反射机制如何床架一个对象
 */
public class ReflectDemo7 {
	public static void main(String[] args) throws Exception {
		//获取类
		Class<?> aClass = Class.forName("com.project.bean.Student");
		Object student = aClass.newInstance();
		//获取修饰符
		int modifiers1 = aClass.getModifiers();
		String s1 = Modifier.toString(modifiers1);
		String simpleName = aClass.getSimpleName();
		String join = s1 + " " + "class" + " " + simpleName + "{\t\n";
		//获取类当中的属性字段
		Field[] fields = aClass.getDeclaredFields();
		StringBuilder sbr = new StringBuilder();
		sbr.append(join);
		Arrays.stream(fields).forEach(field -> {
			//先给他打破封装
			field.setAccessible(true);
			//在这个不一定好用对于一些其他的类型String
			//这个其他的类型肯定是有做这个处理的
			//这一步十分的关键
			//获取修饰
			int modifiers = field.getModifiers();
			String s2 = Modifier.toString(modifiers);
			sbr.append(s2);//追加这个访问修饰符号
			//获取类型
			String simpleName1 = field.getType().getSimpleName();
			sbr.append(" " + simpleName1 + "\t");
			//追加类型
			sbr.append(field.getName());
			//追加一个等号但是这个地方需要做以一个判断就是我们有的内容采取做一个追加没有的话就不要·去追加或者内容了
			//追加这个属性的值
			if (!s2.contains("final")) {
				String simpleNames = field.getType().getSimpleName();
				switch (simpleNames) {
					case "String":
						try {
							// 获取String类型的值
							String stringValue = (String) field.get(student);
							if (stringValue != null) {
								sbr.append(" = ");
								sbr.append(stringValue);
							}
							
							System.out.println("原始String值: " + stringValue);
							// 给String类型的字段赋新值
							field.set(student, "新的值");
							stringValue = (String) field.get(student);
							System.out.println("修改后的String值: " + stringValue);
						} catch (IllegalAccessException e) {
							throw new RuntimeException(e);
						}
						break;
					case "int":
						try {
							// 获取int类型的值
							int intValue = field.getInt(student);
							System.out.println("原始int值: " + intValue);
							if (intValue != 0) {
								sbr.append(" = ");
								sbr.append(intValue);
							}
							// 给int类型的字段赋新值
							field.set(student, 12);
							intValue = field.getInt(student);
							System.out.println("修改后的int值: " + intValue);
						} catch (IllegalAccessException e) {
							throw new RuntimeException(e);
						}
						break;
					case "boolean":
						try {
							// 获取boolean类型的值
							boolean booleanValue = field.getBoolean(student);
							System.out.println("原始boolean值: " + booleanValue);
							if (booleanValue) {
								sbr.append(" = true");
							}
							// 给boolean类型的字段赋新值
							field.setBoolean(student, !booleanValue);
							booleanValue = field.getBoolean(student);
							System.out.println("修改后的boolean值: " + booleanValue);
						} catch (IllegalAccessException e) {
							throw new RuntimeException(e);
						}
						break;
					case "long":
						try {
							// 获取long类型的值
							long longValue = field.getLong(student);
							System.out.println("原始long值: " + longValue);
							// 给long类型的字段赋新值
							field.setLong(student, 12L);
							longValue = field.getLong(student);
							System.out.println("修改后的long值: " + longValue);
						} catch (IllegalAccessException e) {
							throw new RuntimeException(e);
						}
						break;
					case "char":
						try {
							// 获取char类型的值
							char charValue = field.getChar(student);
							System.out.println("原始char值: " + charValue);
							// 给char类型的字段赋新值
							field.setChar(student, 'A');
							charValue = field.getChar(student);
							System.out.println("修改后的char值: " + charValue);
						} catch (IllegalAccessException e) {
							throw new RuntimeException(e);
						}
						break;
					default:
						System.out.println("其他类型: " + simpleName);
				}
			} else {
				// 获取被final修饰的字段的值
				try {
					Object value = field.get(student);
					sbr.append(" = " + value);
					System.out.println("final修饰的字段值: " + value);
				} catch (IllegalAccessException e) {
					throw new RuntimeException(e);
				}
			}
			sbr.append(";\n");
		});
		sbr.append("}");
		System.out.println(sbr.toString());
	}
}

七.通过反射机制来读取方法这个只是介绍了一下里面的方法但是并没有具体的进行拼接这个方法

package com.project.Reflect;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class ReflectDemo9 {
	public static void main(String[] args) throws Exception{
		Class<?> aClass = Class.forName("com.project.Service.UserService");
		Method[] declaredMethods = aClass.getDeclaredMethods();
		//一共的得到了两个方法
		for (Method method : declaredMethods) {
//			System.out.println(method.getName());
			String name = method.getName();
//			获取方法的返回值类型
			Class<?> returnType = method.getReturnType();
//			System.out.println(returnType.getName());
			String simpleName = returnType.getSimpleName();
//			获取这个简类名
//			获取修饰符列表
			int modifiers = method.getModifiers();
			String s = Modifier.toString(modifiers);
//			System.out.println(s);
//			获取参数列表
			Class<?>[] parameterTypes = method.getParameterTypes();
			for (Class<?> parameterType : parameterTypes) {
				System.out.println(parameterType.getSimpleName());
			}
		}
	}
}

八拼接所有的方法

package com.project.Reflect;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

/**
 * 反编译
 */
public class ReflectDemo10 {
	public static void main(String[] args)  throws Exception{
		StringBuilder sbr = new StringBuilder();
		Class<?> aClass = Class.forName("java.lang.String");
		sbr.append(Modifier.toString(aClass.getModifiers())+" class "+aClass.getSimpleName()+"\t\n"+"{\n");
//		System.out.println(sbr.toString());
//		获取方法
		Method[] methods = aClass.getDeclaredMethods();
		for (Method method : methods) {
//			追加一个修饰符
			sbr.append(Modifier.toString(method.getModifiers())+"\t ");
//			追加返回值的类型
			sbr.append(method.getReturnType().getSimpleName()+"\t ");
//			追加一个方法名
			sbr.append(method.getName()+"\t ");
//			追加一个(
			sbr.append("(");
//			追加参数列表
			Class<?>[] parameterTypes = method.getParameterTypes();
			for (int i = 0; i < parameterTypes.length; i++) {
				sbr.append(parameterTypes[i].getSimpleName()+" arg"+i);
				if (i!=parameterTypes.length-1)
				{
					sbr.append(",");
				}
			}
//			追加里面的内容
//			其实最难的就是我们的内容这个是最难的
			sbr.append("System.out.println(\"你好\")");
			sbr.append("\n");
		}
		sbr.append("}");
		System.out.println(sbr);
	}
}

九.通过这个反射机制去调用一个普通的方法

package com.project.Reflect;

import java.lang.reflect.Method;

/**
 * 通过反射机制如何去调用一个对象的方法
 */
public class ReflectDemo11 {
	public static void main(String[] args)  throws Exception{
		Class<?> aClass = Class.forName("com.project.Service.UserService");
		Object object = aClass.newInstance();
//		System.out.println(object);
//		可以把这个变化的内容都写到这个配置文件当中就欧克了这个java代码不需要去修改这个就是反射机制的魅力
//		获取这个方法
		Method[] declaredMethods = aClass.getDeclaredMethods();
		for (Method method : declaredMethods) {
//			System.out.println(method.getName());
			String name = method.getName();
			if (name.equals("login")) {
//				获取到了参数列表
				Method methodss = aClass.getDeclaredMethod(name, String[].class);
//				System.out.println(methodss);
//				调用这个方法
				// 设置参数
				String[] names = {"admin", "123456"};
				Object invoke = methodss.invoke(object, (Object) names);
				System.out.println(invoke.toString());
//				通过这个反射机制去调用这个方法
			}else{
				System.out.println("退出方法暂时不要去执行");
			}
		}
	}
}

十拼接一个完整的含有构造方法的方法

package com.project.Reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

/**
 * 获取这个构造方法
 */
public class ReflectDemo12  {
	public static void main(String[] args) throws Exception {
		StringBuilder sbr = new StringBuilder();
		Class<?> aClass = Class.forName("com.project.bean.Vip");
//		追加包名
//		获取这个类的绝对路径
//		URL resource = ClassLoader.getSystemClassLoader().getResource("com/project/bean/Vip.class");
//		System.out.println(resource);
//追加一个package
		sbr.append("package; ");
//	    追加完整的包名
		String[] s2 = aClass.getName().split("\\.Vip");
		sbr.append(s2[0]+"\n");
//		获取实际的字段一会需要使用
		Map<String,String> Fieldmap=new HashMap<>();
		Field[] fields = aClass.getDeclaredFields();
		for (int i = 0; i < fields.length; i++) {
			Fieldmap.put(fields[i].getType().getSimpleName(),fields[i].getName());
		}
		System.out.println(Fieldmap);
//		获取类名并且给他拼接出一个完整的类
		int modifiers = aClass.getModifiers();
		String s = Modifier.toString(modifiers);
		sbr.append(s);
//		拼接这个class
		sbr.append(" class ");
//		拼接这个类名
		sbr.append(aClass.getSimpleName());
//		拼接这个{
		sbr.append("{\n");
//		打印输出一下
//		System.out.println(sbr);
		//		追加字段
		for (Field field : fields) {
//			追加字段的修饰符号
			int modifiers1 = field.getModifiers();
			String s1 = Modifier.toString(modifiers1);
			sbr.append(s1);
//			追加类型
			String simpleName = field.getType().getSimpleName();
			sbr.append("\t"+simpleName);
//			追加字段名
			sbr.append(" "+field.getName()+";");
//			追加以换行
			sbr.append("\n");
		}
//		拼接构造方法
		Constructor<?>[] constructors = aClass.getConstructors();
		for (Constructor<?> constructor : constructors) {
//			System.out.println(constructor);
//			获取这个构造方法的修饰符号
			int modifiers1 = constructor.getModifiers();
			String s1 = Modifier.toString(modifiers1);
			sbr.append(" "+s1);
//			获取这个构造方法的返回值的类型
			String simpleName = aClass.getSimpleName();
			sbr.append(" "+simpleName);
//			追加以一个(
			sbr.append("(");
//			获取他的参数类型
			Class<?>[] parameterTypes = constructor.getParameterTypes();
			for (int i = 0; i < parameterTypes.length; i++) {
				sbr.append(parameterTypes[i].getSimpleName());
//				追加这个形式参数随便一点就行
				sbr.append(" "+"args"+i);
//				追加一个,
				if (i != parameterTypes.length-1) {
					sbr.append(",");
				}
			}
//			追加一个)
			sbr.append("){\n");
//			追加里面的内容  你也不知道这个参数有几个但是你知道的是这个参数的形式一般是什样的
 			for (int i = 0; i < parameterTypes.length; i++) {
//				String sss = "this.实际参数=虚拟参数";
//				 这个地方就需要停一下这个获取这个实际字段了
				sbr.append("\tthis.");
//				每一次获取完之后后就给他销毁掉
//				sbr.append(Fieldmap.get(parameterTypes[i].getSimpleName()));
//				Field[] fields1 = aClass.getDeclaredFields();
//				for (Field field : fields1) {
//
//				}
//				追加一个等于
				sbr.append("=");
//				追加形式参数列表这个一定要和这个前面的对应起来
				sbr.append("args"+i+";");
//				获取实际参数字段
				sbr.append("\n");
			}
			 sbr.append("       }\n");
		}
		sbr.append("}");
		System.out.println(sbr.toString());
	}
}

十一通过有参数的构造方法和这个无参数的构造方法来创建这个对象

package com.project.Reflect;

import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;

/**
 * 使用这个有参构造方法来创建这个对象
 */
public class ReflectDemo13 {
	public static void main(String[] args) throws Exception {
		Class<?> aClass = Class.forName("com.project.bean.Vip");
		Constructor<?>[] constructors = aClass.getDeclaredConstructors();
		for (Constructor<?> constructor : constructors) {
//			System.out.println(constructor);
//			获取这个参数
			List<Class> list=new ArrayList<>();
			Class<?>[] parameterTypes = constructor.getParameterTypes();
			for (Class<?> parameterType : parameterTypes) {
				  list.add(parameterType);
			}
//			System.out.println(list);
//			通过这个构造函数的参进行new一个对象
//			Object o = constructor.newInstance(list[i]);
		}
		/**
		 * 现在用这个还是比较好用的
		 */
		Constructor<?> con = aClass.getDeclaredConstructor(int.class, String.class, String.class);
		Object o = con.newInstance(1, "23", "234");
		System.out.println(o.toString());
		
		Constructor<?> constructor = aClass.getDeclaredConstructor();
		Object o1 = constructor.newInstance();
		System.out.println(o1.toString());
	}
}

十二.最后这个地方还有一个可变参数的问题

package com.project.Reflect;

import java.util.Arrays;

/**
 * 这个文件还是需要打包的起义后在看起来也方便一点
 * 可变长度的参数可以被当作一个数组的形式出现
 */
public class ArgsTest {
	public static void main(String[] args) {
		       m();
			   m2("aSD",12,12,3213,3213);
			   m3("12","323","232");
			   //传递一个数组
			   m3("1122","RER","GFGD");
	}
	/*
	*可变参数
	 */
	public static void m(int... args)
	{
		System.out.println("方法别执行了");
	}
	/**
	 * 可变参数
	 * 只能出现一个而且之稚只能出现以一个不可以是多个
	 */
	public static void m2(String a,int ... args){
		Arrays.stream(args).forEach(value -> {
			System.out.println(value);
		});
		System.out.println("可变长度参数只能有一个并且");
	}
	/**
	 * 可变数组参数
	 * 可以将这个当作一个数组来看
	 */
	public static void m3(String ... args)
	{
		Arrays.stream(args).forEach(s -> {
			System.out.println(s);
		});
	}
}

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值