getClass(),class属性和getName()解析getGenericSuperclass

本文深入探讨Java反射机制,包括如何获取Class对象、不同方法的区别及其应用场景。通过具体实例讲解getClass()、.class、forName()及newInstance()的使用,帮助读者理解反射在Java中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A   a; 
a.getClass(); 
将返回a对象的信息描述,当然这些信息都是动态的,比如a对象的某个属性有什么值阿等等,你可以在程序运行时通过写代码动态的获得这些信息。getClass().getName()是用来返回Class对象所代表的具体对象的名称。</span>

 
<span style="font-size:18px;">public class Person<T> {

}

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class Student extends Person<Student> {
public static void main(String[] args) {
Student st=new Student();
Class clazz=st.getClass();
//getSuperclass()获得该类的父类
System.out.println(clazz.getSuperclass());
//getGenericSuperclass()获得带有泛型的父类
//Type是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。
Type type=clazz.getGenericSuperclass();
System.out.println(type);
//ParameterizedType参数化类型,即泛型
ParameterizedType p=(ParameterizedType)type;
//getActualTypeArguments获取参数化类型的数组,泛型可能有多个
Class c=(Class) p.getActualTypeArguments()[0];
System.out.println(c);
}
}

打印结果:

class com.test.Person
com.test.Person<com.test.Student>
class com.test.Student</span>

getClass方法:
类型:public final Class<? extends Object> getClass()
功能:返回该对象的运行时类的java.lang.Class对象(API上的解释)
有方法类型可以知道,该方法只能由类的实例变量调用
例子:

[java]  view plain copy
  1. JButton b1 = new JButton("button1");  
  2. System.out.println(b1.getClass());  

输出:
class javax.swing.JButton

class属性
当你要获得一个类的Class对象时(作函数参数的时候),你不能调用getClass方法,那你只能用类名.class来达到效果
例子:

 

 

[java]  view plain copy
  1. System.out.println(JButton.class);  

输出:
class javax.swing.JButton

getName方法:
类型:public String getName()
功能:以String形式返回次Class对象所表示的实体名称
例子:

[java]  view plain copy
  1. JButton b1 = new JButton("button1");  
  2. System.out.println(b1.getName());  

输出:
javax.swing.JButton

可以发现用class属性和getClass返回的输出是一样的,用getName返回的比前面两种少了class和一个空格。

 

.eclipse工具 可以按"."然后马上提示很多方法 供你选择
那他如何知道"."了以后有哪些方法?
他用的语法就是getClass().getMethods();

 

 

 

 

二、

.class其实是在java运行时就加载进去的

getClass()是运行程序时动态加载的

下面以例子说明:


 
  1. 首先建一个基类Baseclass  
  2.   
  3. package  classyongfa;  
  4.   
  5. public  class  Baseclass {  
  6.   
  7. private  String height;  
  8. public  String getHeight()  
  9. {  
  10.    return  height;  
  11. }  
  12.   
  13. public  void  setHeight(String height)  
  14. {  
  15.     
  16.    this .height=height;  
  17.     
  18. }  
  19. 下面是继承Baseclass类Extendclass  
  20.   
  21. package  classyongfa;  
  22.   
  23. public  class  Extendclass extends  Baseclass {  
  24.   
  25. private  String width;  
  26. public  String getWidth()  
  27. {  
  28.    return  width;  
  29. }  
  30.   
  31. public  void  setWidth(String width)  
  32. {  
  33.     
  34.    this .width=width;  
  35.     
  36. }  
  37. public  static  void  main(String[] arg0)  
  38. {  
  39.    Baseclass baseclass1=new  Extendclass();  
  40.    Baseclass baseclass2=new  Baseclass();  
  41.    System.out.println(baseclass1.getClass().getSimpleName());//实际运行的是继承类Extendclass   
  42.   
  43. System.out.println(baseclass2.getClass().getSimpleName());//实际运行的是Baseclass   
  44.   
  45.   
  46.    System.out.println(Baseclass.class .getSimpleName());//加载时类名   
  47. System.out.println(Extendclass.class .getSimpleName());//加载时类名   
  48.   
  49. }  
  50.   
  51. 结果是  
  52.   
  53. Extendclass  
  54. Baseclass  
  55. Baseclass  
  56. Extendclass

 

 

三、 四种获取Class对象的方法 Java反射机制

下面以一个具体的实例来说明。此实例来自《精通Hibernate 3.0 Java数据库持久层开发实践》一书。

先在com.hqh.reflect下建一个文件UseInfojava

package com.hqh.reflect;

public class UseInfo {

private Integer id;
private String userName;
private String password;

public Integer getId() {
   return id;
}

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

public String getUserName() {
   return userName;
}

public void setUserName(String userName) {
   this.userName = userName;
}

public String getPassword() {
   return password;
}

public void setPassword(String password) {
   this.password = password;
}

}

package com.hqh.reflect;

public class GetClassTest {

public static void main(String[] args) {
   GetClassTest test = new GetClassTest();
   if(test.ClassCheck())
    System.out.println("OK");

}

public boolean ClassCheck() {
   try {
    System.out.println("通过类本身获得对象");
    Class userClass = this.getClass() ;
    System.out.println(userClass.getName());
    System.out.println("===========");
   
    System.out.println("通过子类的实例获得父类对象");
    UseInfo useInfo = new UseInfo();
    userClass = useInfo.getClass();
    System.out.println(userClass.getName());
    Class subUserClass = userClass.getSuperclass() ;
    System.out.println(subUserClass.getName());
    System.out.println("===========");
   
    System.out.println("通过类名.class获取对象");
    Class forClass = com.hqh.reflect.UseInfo.class ;
    System.out.println(forClass.getName());
    System.out.println("===========");
   
    System.out.println("通过类名的字符串获取对象");
    Class forName = Class.forName("com.hqh.reflect.UseInfo") ;
    System.out.println(forName.getName());
    System.out.println("=============");
   
   } catch (Exception e) {
    e.printStackTrace();
    return false;
   }
   return true;
}
}


结果:

通过类本身获得对象
com.hqh.reflect.GetClassTest
===========
通过子类的实例获得父类对象
com.hqh.reflect.UseInfo
java.lang.Object
===========
通过类名.class获取对象
com.hqh.reflect.UseInfo
===========
通过类名的字符串获取对象
com.hqh.reflect.UseInfo
=============
OK



在初始化一个 类,生成一个实例的时候,newInstance()方法和new关键字除了一个是方法,一个是关键字外,最主要有什么区别?它们的区别在于创建对象的方 式不一样,前者是使用类加载机制,后者是创建一个新类。那么为什么会有两种创建对象方式?这主要考虑到软件的可伸缩、可扩展和可重用等软件设计思想。 

Java中工厂模式经常使用newInstance()方法来创建对象,因此从为什么要使用工厂模式上可以找到具体答案。 例如: 
class c = Class.forName(“Example”); 
factory = (ExampleInterface)c.newInstance(); 

其中ExampleInterface是Example的接口,可以写成如下形式: 
String className = "Example"; 
class c = Class.forName(className); 
factory = (ExampleInterface)c.newInstance(); 

进一步可以写成如下形式: 
String className = readfromXMlConfig;//从xml 配置文件中获得字符串 
class c = Class.forName(className); 
factory = (ExampleInterface)c.newInstance(); 

上面代码已经不存在Example的类名称,它的优点是,无论Example类怎么变化,上述代码不变,甚至可以更换Example的兄弟类Example2 , Example3 , Example4……,只要他们继承ExampleInterface就可以。 

从JVM的角度看,我们使用关键字new创建一个类的时候,这个类可以没有被加载。但是使用newInstance()方法的时候,就必须保证:1、这个 类已经加载;2、这个类已经连接了。而完成上面两个步骤的正是Class的静态方法forName()所完成的,这个静态方法调用了启动类加载器,即加载 java API的那个加载器。 

现在可以看出,newInstance()实际上是把new这个方式分解为两步,即首先调用Class加载方法加载某个类,然后实例化。 这样分步的好处是显而易见的。我们可以在调用class的静态加载方法forName时获得更好的灵活性,提供给了一种降耦的手段。 

最后用最简单的描述来区分new关键字和newInstance()方法的区别: 
newInstance: 弱类型。低效率。只能调用无参构造。 
new: 强类型。相对高效。能调用任何public构造。

Class aClass = Class.forName(xxx.xx.xx);
Object anInstance = aClass.newInstance();


Class.forName("").newInstance()返回的是object
but there is some limit for this method to create instance
that is your class constructor should no contain parameters, and you should cast the instance manually.

Class Driver{
protected static Driver current;
public static Driver getDriver(){
return current;
}
}

Class MyDriver extends Driver{
static{
Driver.current=new MyDriver();
}
MyDriver(){}
}

用时:
Class.forName("MyDriver");
Driver d=Driver.getDriver();

有的jdbc连接数据库的写法里是Class.forName(xxx.xx.xx);而有一些:Class.forName(xxx.xx.xx).newInstance(),为什么会有这两种写法呢?

Class.forName(xxx.xx.xx) 返回的是一个类,
.newInstance() 后才创建一个对象

Class.forName(xxx.xx.xx);的作用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段

在JDBC规范中明确要求这个Driver类必须向DriverManager注册自己,即任何一个JDBC Driver的Driver类的代码都必须类似如下:
public class MyJDBCDriver implements Driver {
static {
DriverManager.registerDriver(new MyJDBCDriver());
}
}

所以我们在使用JDBC时只需要Class.forName(XXX.XXX);就可以了

we just want to load the driver to jvm only, but not need to user the instance of driver, so call Class.forName(xxx.xx.xx) is enough, if you call Class.forName(xxx.xx.xx).newInstance(), the result will same as calling Class.forName(xxx.xx.xx), because Class.forName(xxx.xx.xx).newInstance() will load driver first, and then create instance, but the instacne you will never use in usual, so you need not to create it.

在JDBC驱动中,有一块静态代码,也叫静态初始化块,它执行的时间是当class调入到内存中就执行(你可以想像成,当类调用到内存后就执行一个方法)。所以很多人把jdbc driver调入到内存中,再实例化对象是没有意义的。

 我们知道在Java中一切都是对象,我们一般所使用的对象都直接或间接继承自Object类。Object类中包含一个方法名叫getClass,利用这个方法就可以获得一个实例的类型类。类型类指的是代表一个类型的类,因为一切皆是对象,类型也不例外,在Java使用类型类来表示一个类型。所有的类型类都是Class类的实例。例如,有如下一段代码:

A a = new A();

if(a.getClass()==A.class)

System.out.println("equal");

else System.out.println("unequal");

结果就是打印出 “equal”。

    可以看到,对象a是A的一个实例,A某一个类,在if语句中使用a.getClass()返回的结果正是A的类型类,在Java中表示一个特定类型的类型类可以用“类型.class”的方式获得,因为a.getClass()获得是A的类型类,也就是A.class,因此上面的代码执行的结果就是打印出 “equal”。特别注意的是,类型类是一一对应的,父类的类型类和子类的类型类是不同的,因此,假设A是B的子类,那么如下的代码将得到 “unequal”的输出:

A a = new A();

if(a.getClass()==B.class)

System.out.println("equal");

else System.out.println("unequal");

因此,如果你知道一个实例,那么你可以通过实例的“getClass()”方法获得该对象的类型类,如果你知道一个类型,那么你可以使用“.class”的方法获得该类型的类型类。

2,获得类型的信息

在获得类型类之后,你就可以调用其中的一些方法获得类型的信息了,主要的方法有:

getName():String:获得该类型的全称名称。

getSuperClass():Class:获得该类型的直接父类,如果该类型没有直接父类,那么返回null。

getInterfaces():Class[]:获得该类型实现的所有接口。

isArray():boolean:判断该类型是否是数组。

isEnum():boolean:判断该类型是否是枚举类型。

isInterface():boolean:判断该类型是否是接口。

isPrimitive():boolean:判断该类型是否是基本类型,即是否是int,boolean,double等等。

isAssignableFrom(Class cls):boolean:判断这个类型是否是类型cls的父(祖先)类或父(祖先)接口。

getComponentType():Class:如果该类型是一个数组,那么返回该数组的组件类型。

此外还可以进行类型转换这类的操作,主要方法有:

asSubclass(Class clazz):Class:将这个类型


package com.kucun.Service; import java.io.Serializable; import java.lang.reflect.*; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.data.domain.Example; import org.springframework.data.domain.ExampleMatcher; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Service; import com.kucun.data.entity.Bancai; import com.kucun.data.entity.Dingdan_chanpin; import com.kucun.data.entity.Dingdan_chanpin_zujian; import com.kucun.data.entity.EntityBasis; import com.kucun.data.entity.Information; import com.kucun.data.entity.Kucun; import com.kucun.dataDo.BancaiRepository; import com.kucun.dataDo.CaizhiRepository; import com.kucun.dataDo.ChanpinRepository; import com.kucun.dataDo.ChanpinZujianRepository; import com.kucun.dataDo.DingdanChanpinRepository; import com.kucun.dataDo.DingdanChanpinZujianRepository; import com.kucun.dataDo.DingdanRepository; import com.kucun.dataDo.KucunRepository; import com.kucun.dataDo.MupiRepository; import com.kucun.dataDo.UserRepository; import com.kucun.dataDo.ZujianRepository; @Service public class AppService { // 注入所有需要的Repository @Autowired private CaizhiRepository caizhiRepository; @Autowired private BancaiRepository bancaiRepository; @Autowired private ChanpinRepository chanpinRepository; @Autowired private DingdanRepository dingdanRepository; @Autowired private MupiRepository mupiRepository; @Autowired private ZujianRepository zujianRepository; @Autowired private KucunRepository kucunRepository; @Autowired private UserRepository userRepository; @Autowired private ChanpinZujianRepository chanpinZujianRepository; @Autowired private DingdanChanpinZujianRepository dingdanChanpinZujianRepository; @Autowired private DingdanChanpinRepository dingdanChanpinRepository; @Autowired private DynamicRepositoryService repositoryService; @Autowired private EntityDependencyService dependencyService; public Information getAllDataWithChildIdse() { Map<String, Object> response = new HashMap<>(); for (String key : repositoryService.getRepositoryNameMap().keySet()) { response.put(key+"s", (repositoryService.getJpaRepository(key).findAll())); } return Information.NewSuccess(response); } public Information getAllDataWithChildIdse(String e) { JpaRepository<?, ?> jp = repositoryService.getJpaRepository(e); System.out.println(jp); return Information.NewSuccess(jp.findAll()); } public Information getAddEntity(Object e) { Class<?> entityClass = e.getClass(); try { // 处理关联字段 handleAssociations(e); @SuppressWarnings("unchecked") JpaRepository<Object, Serializable> jp = (JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(entityClass); Object savedEntity = jp.save(e); if(savedEntity!=null) { if(savedEntity instanceof Bancai) { initializeKucunForBancai((Bancai)savedEntity); } } return Information.NewSuccess(savedEntity); } catch (Exception ex) { return Information.Newfail(500, "创建失败: " + ex.getMessage(), null); } } // 单独封装库存初始化方法 private void initializeKucunForBancai(Bancai bancai) throws Exception { Kucun kucun = new Kucun(null, bancai, 0); // 初始库存为0 try { bancai.setKucun(kucunRepository.save(kucun)); } catch (Exception e) { // TODO: handle exception throw new Exception("initializeKucunForBancai"+e); } } // 处理关联对象(转换为托管实体) private void handleAssociations(Object entity) throws Exception { Class<?> clazz = entity.getClass(); for (Field field : clazz.getDeclaredFields()) { field.setAccessible(true); Object value = field.get(entity); if (value == null) continue; // 处理单个关联实体 if (isEntityBasisField(field)) { EntityBasis associatedEntity = (EntityBasis) value; JpaRepository<Object, Serializable> repo = (JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(associatedEntity.getClass()); // 获取托管状态的关联实体 Object managedEntity = repo.findById(associatedEntity.getId()) .orElseThrow(() -> new RuntimeException("关联实体不存在")); field.set(entity, managedEntity); } // 处理集合关联 else if (isCollectionField(field)) { Collection<?> collection = (Collection<?>) value; List<Object> managedEntities = new ArrayList<>(); for (Object item : collection) { if (item instanceof EntityBasis) { EntityBasis eb = (EntityBasis) item; JpaRepository<Object, Serializable> repo = (JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(eb.getClass()); Object managedEntity = repo.findById(eb.getId()) .orElseThrow(() -> new RuntimeException("关联实体不存在")); managedEntities.add(managedEntity); } } // 更新集合为托管实体 if (!managedEntities.isEmpty()) { field.set(entity, managedEntities); } } } } /** * 更新 * @param e 实体待id * @return */ /** * 更新实体 * @param e 包含ID的实体 * @return 操作结果 */ public Information getupdateEntity(Object e) { if(e == null) { return Information.Newfail(403, "参数为空", null); } Class<?> entityClass = e.getClass(); try { Field idField = entityClass.getDeclaredField("id"); idField.setAccessible(true); Object idValue = idField.get(e); // 修正:应检查id是否为空,而不是不为空 if(idValue == null) { return Information.Newfail(403, "Id为空", null); } // 获取Repository @SuppressWarnings("unchecked") JpaRepository<Object, Serializable> jp = (JpaRepository<Object, Serializable>) repositoryService.getJpaRepository(entityClass); // 从数据库加载现有实体(托管状态) Object existingEntity = jp.findById((Serializable) idValue) .orElseThrow(() -> new RuntimeException("实体不存在")); // 复制属性(排除关联字段) copyNonNullProperties(e, existingEntity); // 保存托管状态的实体 Object updatedEntity = jp.save(existingEntity); return Information.NewSuccess(updatedEntity); } catch (Exception ex) { return Information.Newfail(500, "更新失败: " + ex.getMessage(), null); } } /** * 删除 * @param entity * @return */ public Information getdeleteEntity(EntityBasis entity) { Map<String, Object> response = new HashMap<>(); JpaRepository<Object, Integer> jp= (JpaRepository<Object, Integer>) repositoryService.getJpaRepository(entity.getClass().getSimpleName().toLowerCase()); if(!jp.existsById(entity.getId())) { return Information.NewFail("没有该数据"); } Object d=jp.findById(entity.getId()).orElse(null); for (Class<?> nt : repositoryService.getRepositoryMap().keySet()) { for (Field ent : nt.getDeclaredFields()) { if(ent.getClass().equals(entity.getClass())) { Object o=null; try { o = nt.newInstance(); ent.set(o, d); } catch (InstantiationException | IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(o); if(getSELECTEntity(o).getData()!=null) { return Information.NewFail("已在其他地方使用了,无法删除"); } } } } try { jp.deleteById(((EntityBasis)entity).getId()); } catch (Exception e) { // TODO: handle exception System.out.println(e.getLocalizedMessage()); } if(jp.existsById(entity.getId())) { System.out.println("删除失败"); return Information.NewFail("删除失败"); } return Information.NewSuccess(response); } // 复制非空属性(忽略关联字段) private void copyNonNullProperties(Object source, Object target) throws IllegalAccessException { Class<?> clazz = source.getClass(); for (Field field : clazz.getDeclaredFields()) { field.setAccessible(true); Object value = field.get(source); // 跳过关联字段特殊字段 if (value != null && !isEntityBasisField(field) && !isCollectionField(field) && !field.getName().equals("id")) { Field targetField; try { targetField = target.getClass().getDeclaredField(field.getName()); targetField.setAccessible(true); targetField.set(target, value); } catch (NoSuchFieldException e) { // 忽略不存在的字段 } } } } // 检查是否为关联实体字段 private boolean isEntityBasisField(Field field) { return EntityBasis.class.isAssignableFrom(field.getType()); } // 检查是否为集合字段 private boolean isCollectionField(Field field) { return Collection.class.isAssignableFrom(field.getType()) || Map.class.isAssignableFrom(field.getType()); } /** * 根据非空属性值动态查询实体 * @param entity 包含查询条件的实体对象(非空属性作为查询条件) * @return 查询结果信息(成功时包含数据列表) */ public <T>Information getSELECTEntity(T entity) { if (entity == null) { return Information.NewFail("查询参数不能为空"); } Class<T> entityClass = (Class<T>) entity.getClass(); try { // 1. 获取非泛型的Repository JpaRepository repository = repositoryService.getJpaRepository(entityClass); // 2. 构建非泛型的Example查询 ExampleMatcher matcher = ExampleMatcher.matching() .withIgnoreNullValues() .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING); // 这里直接使用原始类型Example Example<T> example = Example.of(entity);//he type Example is not generic; it cannot be parameterized with arguments <T>the method of(T) is undefined for the type Example // 3. 执行查询 List<?> result = repository.findAll(example); return Information.NewSuccess(result); } catch (ClassCastException e) { return Information.NewFail("Repository类型不匹配: " + e.getMessage()); } catch (DataAccessException e) { return Information.NewFail("数据库访问错误: " + e.getMessage()); } catch (Exception e) { return Information.NewFail("系统错误: " + e.getMessage()); } } private List<Map<String, Object>> convertEntityBasis(List<EntityBasis> entities) { return entities.stream().map(entity -> { Map<String, Object> map = new HashMap<>(); Field[] fields = entity.getClass().getDeclaredFields(); try { // 添加实体自身的基本字段 map.put("id", entity.getId()); // 处理所有字段 for (Field field : fields) { field.setAccessible(true); // 允许访问私有字段 Object fieldValue = field.get(entity); if (fieldValue != null) { String fieldName = field.getName(); // 处理集合类型关联 if (isCollection(field)) { if (!((Collection<?>) fieldValue).isEmpty()) { List<Map<String, Object>> collectionItems = ((Collection<?>) fieldValue) .stream() .filter(item -> item instanceof EntityBasis) .map(item -> { Map<String, Object> itemMap = new HashMap<>(); itemMap.put("id", ((EntityBasis) item).getId()); return itemMap; }) .collect(Collectors.toList()); map.put(fieldName, collectionItems); } } // 处理单个实体关联 else if (implementsInterface(field, EntityBasis.class)) { Map<String, Object> associatedMap = new HashMap<>(); associatedMap.put("id", ((EntityBasis) fieldValue).getId()); map.put(fieldName, associatedMap); } // 处理其他基本类型字段 else if (!isSpecialField(fieldName)) { map.put(fieldName, fieldValue); } } } } catch (IllegalAccessException e) { e.printStackTrace(); } return map; }).collect(Collectors.toList()); } // 判断是否为特殊字段(需要排除的字段) private boolean isSpecialField(String fieldName) { return fieldName.equals("handler") || fieldName.equals("hibernateLazyInitializer"); } /** *-判断属性是否为集合类型 * @param field * @return */ boolean isCollection(Field field) { Class<?> type = field.getType(); // 检查是否为Java内置集合类型 if (Collection.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type) || type.isArray()) { return true; } // 检查是否实现集合相关接口(如Iterable) for (Class<?> interfaceType : type.getInterfaces()) { if (Iterable.class.isAssignableFrom(interfaceType)) { return true; } } return false; } /** * -判断属性是否实现特定接口 * @param field * @param targetInterface * @return */ boolean implementsInterface(Field field, Class<?> targetInterface) { Class<?> type = field.getType(); // 检查类本身是否实现接口 if (targetInterface.isAssignableFrom(type)) { return true; } // 检查实现的接口是否继承目标接口 for (Class<?> interfaceType : type.getInterfaces()) { if (targetInterface.isAssignableFrom(interfaceType)) { return true; } } return false; } private Object convertDingdanChanpins(List<Dingdan_chanpin> findAll) { // TODO Auto-generated method stub return null; } private Object convertDingdanChanpinZujians(List<Dingdan_chanpin_zujian> findAll) { // TODO Auto-generated method stub return null; } } package com.kucun.Service; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Service; @Service public class DynamicRepositoryService { private final Map<Class<?>, JpaRepository<?, ?>> repositoryMap = new HashMap<>(); private final Map<String, JpaRepository<?, ?>> repositoryNameMap = new HashMap<>(); public Map<String, JpaRepository<?, ?>> getRepositoryNameMap() { return repositoryNameMap; } public Map<Class<?>, JpaRepository<?, ?>> getRepositoryMap() { return repositoryMap; } public JpaRepository<?,?> getJpaRepository(String e){ // System.out.println("String:"+e+mapToString(repositoryNameMap)); return repositoryNameMap.get(e); } public JpaRepository<?,?> getJpaRepository(Class<?> e){ // System.out.println("Class:"+e+mapToString(repositoryMap)); // System.out.println("Class:"+e); return repositoryMap.get(e); } // 自动注入所有JpaRepository实例 @Autowired public void initRepositories(Map<String, JpaRepository<?, ?>> repositories) { repositories.forEach((name, repo) -> { // 获取代理类实现的接口 Class<?>[] interfaces = repo.getClass().getInterfaces(); for (Class<?> iface : interfaces) { // 扫描接口上的泛型信息 Type[] genericInterfaces = iface.getGenericInterfaces(); for (Type type : genericInterfaces) { if (type instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) type; // 检查原始类型是否是JpaRepository if (pt.getRawType().equals(JpaRepository.class)) { Type[] args = pt.getActualTypeArguments(); if (args.length >= 2 && args[0] instanceof Class) { Class<?> entityClass = (Class<?>) args[0]; repositoryMap.put(entityClass, repo); String key = entityClass.getSimpleName().toLowerCase(); repositoryNameMap.put(key, repo); // 调试日志 System.out.printf("Mapped %s -> %s [key: %s]%n", entityClass.getName(), repo.getClass().getName(), key); } } } } // 检查接口本身的泛型签名(如果继承的是参数化接口) Type genericSuper = iface.getGenericSuperclass(); if (genericSuper instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) genericSuper; if (pt.getRawType().equals(JpaRepository.class)) { Type[] args = pt.getActualTypeArguments(); if (args.length >= 2 && args[0] instanceof Class) { Class<?> entityClass = (Class<?>) args[0]; repositoryMap.put(entityClass, repo); String key = entityClass.getSimpleName().toLowerCase(); repositoryNameMap.put(key, repo); // 调试日志 System.out.printf("Mapped %s -> %s [key: %s]%n", entityClass.getName(), repo.getClass().getName(), key); } } } } }); } // 通用保存方法 public <T> T saveEntity(T entity) { JpaRepository<T, ?> repo = (JpaRepository<T, ?>) repositoryMap.get(entity.getClass()); if (repo != null) { return repo.save(entity); } throw new IllegalArgumentException("Repository not found for " + entity.getClass()); } public static String mapToString(Map<?, ?> map) { if (map == null || map.isEmpty()) { return ""; } StringBuilder sb = new StringBuilder(); for (Map.Entry<?, ?> entry : map.entrySet()) { sb.append(entry.getKey()).append("=").append(entry.getValue()).append(","); } // 删除最后一个多余的逗号 if (sb.length() > 0) { sb.setLength(sb.length() - 1); } return sb.toString(); } }package com.kucun.Service; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; import javax.persistence.metamodel.*; import org.springframework.stereotype.Service; import java.io.Serializable; import java.util.*; import java.util.stream.Collectors; @Service public class EntityDependencyService { @PersistenceContext private EntityManager entityManager; private final Map<Class<?>, Set<Attribute<?, ?>>> associationCache = new HashMap<>(); /** * 检查实体是否被其他实体引用 * @param entityClass 实体类 * @param entityId 实体ID * @return 存在引用返回true */ public boolean hasDependencies(Class<?> entityClass, Serializable entityId) { Metamodel metamodel = entityManager.getMetamodel(); Set<EntityType<?>> entities = metamodel.getEntities(); for (EntityType<?> entityType : entities) { // 跳过自身(避免自引用检查) if (entityType.getJavaType().equals(entityClass)) continue; Set<Attribute<?, ?>> associations = getAssociationAttributes(entityType); for (Attribute<?, ?> attr : associations) { if (attr.getJavaType().isAssignableFrom(entityClass)) { if (isReferenced(entityType, attr, entityId)) { return true; } } } } return false; } /** * 获取实体所有关联属性(带缓存) */ private Set<Attribute<?, ?>> getAssociationAttributes(EntityType<?> entityType) { return associationCache.computeIfAbsent(entityType.getJavaType(), k -> entityType.getAttributes().stream() .filter(Attribute::isAssociation) .collect(Collectors.toSet()) ); } /** * 检查特定关联是否引用目标实体 */ private boolean isReferenced(EntityType<?> entityType, Attribute<?, ?> attribute, Serializable targetId) { String jpql = buildReferenceQuery(entityType, attribute); Long count = (Long) entityManager.createQuery(jpql) .setParameter("targetId", targetId) .getSingleResult(); return count > 0; } /** * 构建引用检查查询 */ private String buildReferenceQuery(EntityType<?> entityType, Attribute<?, ?> attribute) { String entityName = entityType.getName(); String attrName = attribute.getName(); if (attribute instanceof PluralAttribute) { return String.format("SELECT COUNT(e) FROM %s e WHERE :targetId MEMBER OF e.%s", entityName, attrName); } else { return String.format("SELECT COUNT(e) FROM %s e WHERE e.%s.id = :targetId", entityName, attrName); } } }完善删除功能尽量简洁
最新发布
06-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值