public class ReflectDemo1 {
public static void main(String[] args) throws ClassNotFoundException {
//基本类型直接通过 基本类型。class就可以获得
Class stringClass = String.class;
Class integerClass = Integer.class;
System.out.println("integerClass = " + integerClass);
String name = stringClass.getName();
System.out.println("name = " + name);
String simpleName = stringClass.getSimpleName();
System.out.println("simpleName = " + simpleName);
String name1 = stringClass.getPackage().getName();
System.out.println("name1 = " + name1);
Package aPackage = stringClass.getPackage();
System.out.println("aPackage = " + aPackage);
Method[] methods = stringClass.getMethods();
for (Method m:methods) {
System.out.println("m = " + m);
}
Method[] declaredMethods = stringClass.getDeclaredMethods();
for (Method md:declaredMethods) {
System.out.println("md = " + md);
}
ClassLoader classLoader = stringClass.getClassLoader();
System.out.println("classLoader = " + classLoader);
System.out.println("stringClass = " + stringClass);
//第二种方式是通过forName形式获得 里面传递的参数是包名+类名
Class> aClass = Class.forName("java.lang.String");
System.out.println("aClass = " + aClass);
}
}
public class ReflectDemo3 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
Person person=new Person("lisi",28);
System.out.println("person = " + person);
//通过构造器实例化对象
String name="reflect.Person";
Class> aClass = Class.forName(name);
System.out.println("aClass = " + aClass);
Constructor> constructor = aClass.getConstructor(String.class, int.class);
Object lisi = constructor.newInstance("lisi", 30);
System.out.println("lisi = " + lisi);
}
}
public class ReflectDemo8 {
public static void main(String[] args) throws URISyntaxException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {
Class reflectDemo8Class = ReflectDemo8.class;
System.out.println("reflectDemo8Class = " + reflectDemo8Class);
URL resource = reflectDemo8Class.getResource(".");
System.out.println("resource = " + resource);
URI uri = resource.toURI();
System.out.println("uri = " + uri);
File file1 = new File(uri);
System.out.println("file1 = " + file1);
File[] files = file1.listFiles();
for (File file : files) {
System.out.println("file = " + file);
boolean b = file.getName().endsWith(".class");
if(b){
String name = file.getName();
System.out.println("name = " + name);
String substring = name.substring(0, name.indexOf("."));
System.out.println("substring = " + substring);
Class> aClass = Class.forName(ReflectDemo8.class.getPackage().getName() + "." + substring);
System.out.println("aClass = " + aClass);
if(aClass.isAnnotationPresent(AutoRunClass.class)){
Object o = aClass.newInstance();
Method[] declaredMethods = aClass.getDeclaredMethods();
for(Method method : declaredMethods){
boolean annotationPresent = method.isAnnotationPresent(AutoRunMethod.class);
if(annotationPresent){
Object invoke = method.invoke(o);
System.out.println("invoke = " + invoke);
}
}
}
}
}
}
以上是代码的一个练习,下面是每一步应该做什么
反射是Java语言的一个重要特性,它允许程序在运行时动态地获取类的信息,包括类名、属性、方法、构造器等,可以使得程序更加灵活、易于扩展。下面是对Java反射的详细讲解和示例代码。
反射是指在程序运行时动态地获取一个类的信息,并且可以在运行时动态地创建对象、调用方法、获取属性等。Java反射的主要操作对象是Class类,也就是Java中的类对象。在Java中,所有的类都有一个Class类的对象,该对象包含了该类的所有信息,例如类名、属性、方法、构造器等,这些信息都可以利用反射来获取。
2.1 获取Class对象
在Java中,获取Class对象的方式有三种:
1)使用Class.forName()方法
该方法需要传入一个完整的类名,例如:
Class clazz = Class.forName("com.example.demo.User");
2)使用类的.class属性
该方式是最常用的方式,例如:
Class clazz = User.class;
3)使用对象的getClass()方法
该方法可以获取一个对象的Class对象,例如:
User user = new User();
Class clazz = user.getClass();
2.2 创建对象
在Java中,使用反射可以在运行时动态地创建对象,具体步骤如下:
1)获取Class对象
2)使用Class对象的newInstance()方法创建对象,例如:
Class clazz = Class.forName("com.example.demo.User");
User user = (User) clazz.newInstance();
2.3 调用方法
在Java中,使用反射可以在运行时动态地调用对象的方法,具体步骤如下:
1)获取Class对象
2)使用Class对象的getMethod()方法获取方法对象
3)使用Method对象的invoke()方法调用方法,例如:
Class clazz = Class.forName("com.example.demo.User");
User user = (User) clazz.newInstance();
Method method = clazz.getMethod("setName", String.class);
method.invoke(user, "Tom");
2.4 获取属性
在Java中,使用反射可以在运行时动态地获取对象的属性值,具体步骤如下:
1)获取Class对象
2)使用Class对象的getField()方法获取属性对象
3)使用Field对象的get()方法获取属性值,例如:
Class clazz = Class.forName("com.example.demo.User");
User user = (User) clazz.newInstance();
Field field = clazz.getField("name");
String name = (String) field.get(user);
下面是一个完整的示例代码,包括获取Class对象、创建对象、调用方法、获取属性等操作:
package com.example.demo;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectionDemo {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
//获取Class对象的三种方式
Class clazz = Class.forName("com.example.demo.User");
Class clazz2 = User.class;
User user = new User();
Class clazz3 = user.getClass();
//创建对象
User user1 = (User) clazz.newInstance();
//调用方法
Method method = clazz.getMethod("setName", String.class);
method.invoke(user1, "Tom");
//获取属性
Field field = clazz.getField("name");
String name = (String) field.get(user1);
System.out.println(name);
}
}
package com.example.demo;
public class User {
public String name;
public void setName(String name) {
this.name = name;
}
}
下面是关于Java反射的重要知识点:
获取类型信息:Class类是Java反射的核心类,可以用来获取类、方法、属性等的详细信息。可以通过Class类的forName()方法、类名.class或对象.getClass()方法获取Class对象。
获取属性信息:可以使用Class类的getFields()、getDeclaredFields()、getField()和getDeclaredField()方法获取属性信息。
获取方法信息:可以使用Class类的getMethods()、getDeclaredMethods()、getMethod()和getDeclaredMethod()方法获取方法信息。
获取构造函数信息:可以使用Class类的getConstructors()、getDeclaredConstructors()和getConstructor()方法获取构造函数信息。
动态修改属性值:可以使用Field类的set()方法动态修改属性值。
动态调用方法:可以使用Method类的invoke()方法动态调用方法。
动态创建对象:可以使用Class类的newInstance()方法或Constructor类的newInstance()方法动态创建对象。
获取注解信息:可以使用Class类和Method类的getAnnotation()方法获取注解信息。
动态代理:可以使用Java动态代理实现动态代理对象。
性能问题:由于反射是动态的,所以会引入一些性能问题。需要在合适的时候使用反射,以避免性能问题。