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. CF600E Lomsat gelral 和 CF741D Dokhtar-kosh paths

    Lomsat gelral 一棵以\(1\)为根的树有\(n\)个结点,每个结点都有一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号(若有数量一样的,则求编号和). \(n \le 10^ ...

  2. machine learning (2)-linear regression with one variable

    machine learning- linear regression with one variable(2) Linear regression with one variable = univa ...

  3. 行为型模式(五) 中介者模式(Mediator)

    一.动机(Motivate) 为什么要使用中介者模式呢?如果不使用中介者模式的话,各个同事对象将会相互进行引用,如果每个对象都与多个对象进行交互时,将会形成如下图所示的网状结构.从上图可以发现,如果不 ...

  4. Spring源码窥探之:BeanPostProcessor

    Spring的Bean后置处理器 1. 实体类 /** * @author 70KG * @Title: Train * @Description: * @date 2018/7/23下午11:31 ...

  5. 深入理解flask 笔记

    ===sqlalchemy创建的数据模型中:1 字段是类属性   [模型中定义的字段是类属性,表单中定义的字段也是类字段] 2 若数据库不支持bool类型,则sqlalchemy会自动将bool转成0 ...

  6. LightOJ - 1102 - Problem Makes Problem(组合数)

    链接: https://vjudge.net/problem/LightOJ-1102 题意: As I am fond of making easier problems, I discovered ...

  7. Base64原理解析与使用

    一.Base64编码由来 为什么会有Base64编码呢?因为有些网络传送渠道并不支持所有的字节,例如传统的邮件只支持可见字符的传送,像ASCII码的控制字符就 不能通过邮件传送.这样用途就受到了很大的 ...

  8. FTP与HTTP上传文件的对比

    许多站点,比如facebook或一些博客等都允许用户上传或下载文件,比如论坛或博客系统的图片. 在这种情况下,通常有两种选择上传文件到服务器,那就是FTP协议和HTTP协议. 以下列出了一些两者的不同 ...

  9. 洛谷P1706全排列问题

     P1706 全排列问题 题目描述 输出自然数1到n所有不重复的排列,即n的全排列,要求所产生的任一数字序列中不允许出现重复的数字. 输入输出格式 输入格式: n(1≤n≤9) 输出格式: 由1-n组 ...

  10. AtCoder Grand Contest 003题解

    传送门 \(A\) 咕咕 const int N=1005; char s[N];int val[N],n; int main(){ scanf("%s",s+1),n=strle ...