package com.opslab.util;

import org.apache.log4j.Logger;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
* <h6>Description:<h6>
* <p>Java Class与反射相关的一些工具类</p>
*/
public final class ClassUtil {

/**
* 获取类加载器
*/
public static ClassLoader overridenClassLoader;

public static ClassLoader getContextClassLoader() {
return overridenClassLoader != null ?
overridenClassLoader : Thread.currentThread().getContextClassLoader();
}

private static Logger logger = Logger.getLogger(ClassUtil.class);

/**
* 获取指定类的全部属性字段
*
* @param className 需要获取的类名
* @param extendsField 是否获取接口或父类中的公共属性
* @return 属性字段数组
*/
public final static String[] getField(String className, boolean extendsField) {
Class classz = loadClass(className);
Field[] fields = classz.getFields();
Set<String> set = new HashSet<>();
if (fields != null) {
for (Field f : fields) {
set.add(f.getName());
}
}
if (extendsField) {
Field[] fieldz = classz.getDeclaredFields();
if (fieldz != null) {
for (Field f : fieldz) {
set.add(f.getName());
}
}
}
return set.toArray(new String[set.size()]);
}

/**
* 获取类中的公共属性
*
* @param className 需要获取的类名
* @param extendsField 是否获取接口或父类中的公共属性
* @return 属性字段数组
*/
public final static String[] getPublicField(String className, boolean extendsField) {
Class classz = loadClass(className);
Set<String> set = new HashSet<>();
Field[] fields = classz.getDeclaredFields();
if (fields != null) {
for (Field f : fields) {
String modifier = Modifier.toString(f.getModifiers());
if (modifier.startsWith("public")) {
set.add(f.getName());
}
}
}
if (extendsField) {
Field[] fieldz = classz.getFields();
if (fieldz != null) {
for (Field f : fieldz) {
set.add(f.getName());
}
}
}
return set.toArray(new String[set.size()]);
}

/**
* 获取类中定义的protected类型的属性字段
*
* @param className 需要获取的类名
* @return protected类型的属性字段数组
*/
public final static String[] getProtectedField(String className) {
Class classz = loadClass(className);
Set<String> set = new HashSet<>();
Field[] fields = classz.getDeclaredFields();
if (fields != null) {
for (Field f : fields) {
String modifier = Modifier.toString(f.getModifiers());
if (modifier.startsWith("protected")) {
set.add(f.getName());
}
}
}
return set.toArray(new String[set.size()]);
}

/**
* 获取类中定义的private类型的属性字段
*
* @param className 需要获取的类名
* @return private类型的属性字段数组
*/
public final static String[] getPrivateField(String className) {
Class classz = loadClass(className);
Set<String> set = new HashSet<>();
Field[] fields = classz.getDeclaredFields();
if (fields != null) {
for (Field f : fields) {
String modifier = Modifier.toString(f.getModifiers());
if (modifier.startsWith("private")) {
set.add(f.getName());
}
}
}
return set.toArray(new String[set.size()]);
}

/**
* 获取对象的全部public类型方法
*
* @param className 需要获取的类名
* @param extendsMethod 是否获取继承来的方法
* @return 方法名数组
*/
public final static String[] getPublicMethod(String className, boolean extendsMethod) {
Class classz = loadClass(className);
Method[] methods;
if (extendsMethod) {
methods = classz.getMethods();
} else {
methods = classz.getDeclaredMethods();
}
Set<String> set = new HashSet<>();
if (methods != null) {
for (Method f : methods) {
String modifier = Modifier.toString(f.getModifiers());
if (modifier.startsWith("public")) {
set.add(f.getName());
}
}
}
return set.toArray(new String[set.size()]);
}

/**
* 获取对象的全部protected类型方法
*
* @param className 需要获取的类名
* @param extendsMethod 是否获取继承来的方法
* @return 方法名数组
*/
public final static String[] getProtectedMethod(String className, boolean extendsMethod) {
Class classz = loadClass(className);
Method[] methods;
if (extendsMethod) {
methods = classz.getMethods();
} else {
methods = classz.getDeclaredMethods();
}
Set<String> set = new HashSet<>();
if (methods != null) {
for (Method f : methods) {
String modifier = Modifier.toString(f.getModifiers());
if (modifier.startsWith("protected")) {
set.add(f.getName());
}
}
}
return set.toArray(new String[set.size()]);
}

/**
* 获取对象的全部private类型方法
*
* @param className 需要获取的类名
* @return 方法名数组
*/
public final static String[] getPrivateMethod(String className) {
Class classz = loadClass(className);
Method[] methods = classz.getDeclaredMethods();
Set<String> set = new HashSet<>();
if (methods != null) {
for (Method f : methods) {
String modifier = Modifier.toString(f.getModifiers());
if (modifier.startsWith("private")) {
set.add(f.getName());
}
}
}
return set.toArray(new String[set.size()]);
}

/**
* 获取对象的全部方法
*
* @param className 需要获取的类名
* @param extendsMethod 是否获取继承来的方法
* @return 方法名数组
*/
public final static String[] getMethod(String className, boolean extendsMethod) {
Class classz = loadClass(className);
Method[] methods;
if (extendsMethod) {
methods = classz.getMethods();
} else {
methods = classz.getDeclaredMethods();
}
Set<String> set = new HashSet<>();
if (methods != null) {
for (Method f : methods) {
set.add(f.getName());
}
}
return set.toArray(new String[set.size()]);
}

/**
* 调用对象的setter方法
*
* @param obj 对象
* @param att 属性名
* @param value 属性值
* @param type 属性类型
*/
public final static void setter(Object obj, String att, Object value, Class<?> type)
throws InvocationTargetException, IllegalAccessException {
try {
String name = att.substring(0, 1).toUpperCase() + att.substring(1);
Method met = obj.getClass().getMethod("set" + name, type);
met.invoke(obj, value);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}

}

/**
* 获取指定目录下所有的类名
*
* @param path 包名
* @param childPackage 是否获取子包
*/
public final static List<String> getClassName(String path, boolean childPackage) {
List<String> fileNames = new ArrayList<>();
if (path.endsWith(".jar")) {
fileNames.addAll(getClassNameByJar(path));
} else {
fileNames = getClassNameByFile(path, childPackage);
}
return fileNames;
}

/**
* 从项目文件获取某包下所有类
*
* @param filePath 文件路径
* @param childPackage 是否遍历子包
* @return 类的完整名称
*/
public final static List<String> getClassNameByFile(String filePath, boolean childPackage) {
List<String> myClassName = new ArrayList<>();
List<File> files = FileUtil.listFile(filePath, childPackage);
for (File file : files) {
if (file.getName().endsWith(".class")) {
String childFilePath = file.getPath();
int index = filePath.replaceAll("\\\\", ".").length();
childFilePath = childFilePath.replaceAll("\\\\", ".").substring(index, childFilePath.length());
myClassName.add(childFilePath);
}
}
return myClassName;
}

/**
* 从jar获取某包下所有类
*
* @param jarPath jar文件路径
* @return 类的完整名称
*/
public final static List<String> getClassNameByJar(String jarPath) {
List<String> myClassName = new ArrayList<>();
try (JarFile jarFile = new JarFile(jarPath)) {
Enumeration<JarEntry> entrys = jarFile.entries();
while (entrys.hasMoreElements()) {
JarEntry jarEntry = entrys.nextElement();
String entryName = jarEntry.getName();
if (entryName.endsWith(".class")) {
entryName = entryName.replace("/", ".").substring(0, entryName.lastIndexOf("."));
myClassName.add(entryName);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return myClassName;
}

/**
* 加载指定的类
*
* @param className 需要加载的类
* @return 加载后的类
*/
public final static Class loadClass(String className) {
Class theClass = null;
try {
theClass = Class.forName(className);
} catch (ClassNotFoundException e1) {
logger.error("load class error:" + e1.getMessage());
e1.printStackTrace();
}
return theClass;
}

/**
* 获取jar包中的非*.class外的全部资源文件名字
*
* @param jarPath jar文件路径
* @return 返回资源名称数组
*/
public final static List<String> getResourceNameByJar(String jarPath) {
List<String> resource = new ArrayList<>();
try (JarFile jarFile = new JarFile(jarPath)) {
Enumeration<JarEntry> entrys = jarFile.entries();
while (entrys.hasMoreElements()) {
JarEntry jarEntry = entrys.nextElement();
String entryName = jarEntry.getName();
if (!entryName.endsWith(".class") && !entryName.endsWith("/")) {
resource.add(FilePathUtil.commandPath(jarPath) + "!" + entryName);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return resource;
}

/**
* 获取jar包中的非*.class外的全部的以suffix结尾的资源文件
*
* @param jarPath jar包的路径
* @param suffix 后缀名称
* @return 返回资源名称数组
*/
public final static List<String> getResourceNameByJar(String jarPath, String suffix) {
List<String> resource = new ArrayList<>();
try (JarFile jarFile = new JarFile(jarPath)) {
Enumeration<JarEntry> entrys = jarFile.entries();
while (entrys.hasMoreElements()) {
JarEntry jarEntry = entrys.nextElement();
String entryName = jarEntry.getName();
if (entryName.endsWith(suffix)) {
resource.add(FilePathUtil.commandPath(jarPath) + "!" + entryName);
}
}
} catch (IOException e) {
logger.error(ExceptionUtil.stackTraceToString(e, "com.opslab.util"));
}
return resource;
}

/**
* 获取一个类的父类
*
* @param className 需要获取的类
* @return 父类的名称
*/
public final static String getSuperClass(String className) {
Class classz = loadClass(className);
Class superclass = classz.getSuperclass();
return superclass.getName();
}

/**
* 获取一个雷的继承链
*
* @param className 需要获取的类
* @return 继承类名的数组
*/
public final static String[] getSuperClassChian(String className) {
Class classz = loadClass(className);
List<String> list = new ArrayList<>();
Class superclass = classz.getSuperclass();
String superName = superclass.getName();
if (!"java.lang.Object".equals(superName)) {
list.add(superName);
list.addAll(Arrays.asList(getSuperClassChian(superName)));
} else {
list.add(superName);
}
return list.toArray(new String[list.size()]);
}

/**
* 获取一类实现的全部接口
*
* @param className 需要获取的类
* @param extendsInterfaces 话说getInterfaces能全部获取到才对,然而测试的时候父类的接口并没有
* 因此就多除了这参数
* @return 实现接口名称的数组
*/
public final static String[] getInterfaces(String className, boolean extendsInterfaces) {
Class classz = loadClass(className);
List<String> list = new ArrayList<>();
Class[] interfaces = classz.getInterfaces();
if (interfaces != null) {
for (Class inter : interfaces) {
list.add(inter.getName());
}
}
if (extendsInterfaces) {
String[] superClass = getSuperClassChian(className);
for (String c : superClass) {
list.addAll(Arrays.asList(getInterfaces(c, false)));
}
}
return list.toArray(new String[list.size()]);
}
}

Java Class与反射相关的一些工具类的更多相关文章

  1. java调用kettle的job和transfer工具类

    package com.woaiyitiaocai.util; import java.util.Map; import java.util.UUID; import org.apache.log4j ...

  2. 提供Web相关的个工具类

    package com.opslab.util.web; import com.opslab.util.ConvertUtil;import com.opslab.util.StringUtil; i ...

  3. Java语言Lang包下常用的工具类介绍_java - JAVA

    文章来源:嗨学网 敏而好学论坛www.piaodoo.com 欢迎大家相互学习 无论你在开发哪中 Java 应用程序,都免不了要写很多工具类/工具函数.你可知道,有很多现成的工具类可用,并且代码质量都 ...

  4. java关闭资源,自制关闭资源工具类

    在网上看到一篇关于关闭资源的正确方式:http://blog.csdn.net/bornforit/article/details/6896775 该博文中的总结: (1)使用finally块来关闭物 ...

  5. java中map和对象互转工具类的实现示例

    在项目开发中,经常碰到map转实体对象或者对象转map的场景,工作中,很多时候我们可能比较喜欢使用第三方jar包的API对他们进行转化,而且用起来也还算方便,比如像fastJson就可以轻松实现map ...

  6. 【Java多线程】JUC包下的工具类CountDownLatch、CyclicBarrier和Semaphore

    前言 JUC中为了满足在并发编程中不同的需求,提供了几个工具类供我们使用,分别是CountDownLatch.CyclicBarrier和Semaphore,其原理都是使用了AQS来实现,下面分别进行 ...

  7. Java操作zip压缩和解压缩文件工具类

    需要用到ant.jar(这里使用的是ant-1.6.5.jar) import java.io.File; import java.io.FileInputStream; import java.io ...

  8. JAVA调用操作javascript (JS)工具类

    import java.io.BufferedReader;import java.io.FileNotFoundException;import java.io.FileReader;import ...

  9. Java基础知识强化92:日期工具类的编写和测试案例

    1. DateUtil.java,代码如下: package cn.itcast_04; import java.text.ParseException; import java.text.Simpl ...

随机推荐

  1. NOI.ac 模拟赛20181103 排队 翘课 运气大战

    题解 排队 20% 1≤n≤20,1≤x,hi≤201\le n\le 20, 1\le x,h_i\le 201≤n≤20,1≤x,hi​≤20 随便暴力 50% 1≤n≤2000,1≤x,hi≤1 ...

  2. Chrome抓包小技巧

    1.抓包时如果有页面跳转,记得把preserve log这个选项勾上

  3. Arthas使用指南

    Arthas 能为你做什么? 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception? 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了? 遇到问题无法在预发 de ...

  4. 学习Spring-Data-Jpa(七)---JpaRepository

    之前我们学习的Repository都是Spring-Data为了兼容NoSQL而进行的一些抽象封装,从JpaRepository开始是对关系型数据库进行抽象封装.JpaRepository位于spri ...

  5. 17、stage划分算法原理及DAGScheduler源码分析

    一.stage划分算法原理 1.图解 二.DAGScheduler源码分析 1. ###org.apache.spark/SparkContext.scala // 调用SparkContext,之前 ...

  6. Spring boot 解决跨域问题

    import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.we ...

  7. 《挑战30天C++入门极限》入门教程:实例详解C++友元

        入门教程:实例详解C++友元 在说明什么是友元之前,我们先说明一下为什么需要友元与友元的缺点: 通常对于普通函数来说,要访问类的保护成员是不可能的,如果想这么做那么必须把类的成员都生命成为pu ...

  8. Chrome浏览器控制台[DOM] Password field is not contained in a form:

    [DOM] Password field is not contained in a form: ( [DOM]密码字段不包含在form表单中) 解决方案:添加一层form标签 <div cla ...

  9. Java SpringBoot使用126邮箱发送html内容邮件,带附件

    package mail.demo; import org.junit.Test; import org.junit.runner.RunWith; import org.springframewor ...

  10. Chrome 浏览器中查看 webSocket 连接信息

      1.以下代码实现一个webSocket连接,在文本输入框中输入内容,点击发送,通过服务器,返回相同的内容显示在下方. 1 <!DOCTYPE html> 2 <html lang ...