Java内容重新整理删除过期的东西

This commit is contained in:
estom
2025-09-14 03:49:42 -04:00
parent 9b8524ff80
commit 885b795e45
413 changed files with 643 additions and 1340 deletions

View File

@@ -0,0 +1,25 @@
package cn.aofeng.demo.java.lang.instrument;
import java.lang.instrument.Instrumentation;
import org.apache.commons.lang.StringUtils;
import cn.aofeng.demo.util.LogUtil;
/**
* Instrument入口类。
*
* @author <a href="mailto:aofengblog@163.com">聂勇</a>
*/
public class FirstInstrumentation {
public static void premain(String options, Instrumentation ins) {
if (StringUtils.isBlank(options)) {
LogUtil.log("instrument without options");
} else {
LogUtil.log("instrument with options:%s", options);
}
ins.addTransformer(new FirstTransformer());
}
}

View File

@@ -0,0 +1,26 @@
/**
*
*/
package cn.aofeng.demo.java.lang.instrument;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import cn.aofeng.demo.util.LogUtil;
/**
* 只输出问候语不进行字节码修改的Class转换器。
*
* @author <a href="mailto:aofengblog@163.com">聂勇</a>
*/
public class FirstTransformer implements ClassFileTransformer {
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
LogUtil.log(">>> %s", className);
return null;
}
}

View File

@@ -0,0 +1,14 @@
package cn.aofeng.demo.java.lang.instrument;
/**
* Instrumentation启动类。 *
*
* @author <a href="mailto:aofengblog@163.com">聂勇</a>
*/
public class Hello {
public static void main(String[] args) {
// nothing
}
}

View File

@@ -0,0 +1,40 @@
# 一、Instrumentation入门
* [FirstTransformer.java](FirstTransformer.java) 处理字节码由类FirstInstrumentation执行
* [FirstInstrumentation.java](FirstInstrumentation.java) instrumentation入口类由javaagent载入执行
* [build.xml](build.xml) Ant脚本负责编译、打包和运行
在当前目录下执行命令:
```bash
ant
```
输出信息如下:
> [java] instrument with options:"Hello, Instrumentation"
> [java] >>> java/lang/invoke/MethodHandleImpl
> [java] >>> java/lang/invoke/MethodHandleImpl$1
> [java] >>> java/lang/invoke/MethodHandleImpl$2
> [java] >>> java/util/function/Function
> [java] >>> java/lang/invoke/MethodHandleImpl$3
> [java] >>> java/lang/invoke/MethodHandleImpl$4
> [java] >>> java/lang/ClassValue
> [java] >>> java/lang/ClassValue$Entry
> [java] >>> java/lang/ClassValue$Identity
> [java] >>> java/lang/ClassValue$Version
> [java] >>> java/lang/invoke/MemberName$Factory
> [java] >>> java/lang/invoke/MethodHandleStatics
> [java] >>> java/lang/invoke/MethodHandleStatics$1
> [java] >>> sun/misc/PostVMInitHook
> [java] >>> sun/usagetracker/UsageTrackerClient
> [java] >>> java/util/concurrent/atomic/AtomicBoolean
> [java] >>> sun/usagetracker/UsageTrackerClient$1
> [java] >>> sun/usagetracker/UsageTrackerClient$4
> [java] >>> sun/usagetracker/UsageTrackerClient$3
> [java] >>> java/io/FileOutputStream$1
> [java] >>> sun/launcher/LauncherHelper
> [java] >>> cn/aofeng/demo/java/lang/instrument/Hello
> [java] >>> sun/launcher/LauncherHelper$FXHelper
> [java] >>> java/lang/Class$MethodArray
> [java] >>> java/lang/Void
> [java] >>> java/lang/Shutdown
> [java] >>> java/lang/Shutdown$Lock

View File

@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="Instrumentation" default="run" basedir="../../../../../../../">
<property name="project.src.dir" value="${basedir}/src" />
<property name="project.lib.dir" value="${basedir}/lib" />
<property name="project.conf.dir" value="${basedir}/conf" />
<property name="project.target.dir" value="${basedir}/classes" />
<property name="project.dist.dir" value="${basedir}/dist" />
<path id="project.classpath">
<fileset dir="${project.lib.dir}">
<include name="*.jar" />
</fileset>
</path>
<target name="prepare">
<delete dir="${project.target.dir}" />
<mkdir dir="${project.target.dir}"/>
<copy todir="${project.target.dir}">
<fileset dir="${project.conf.dir}">
<include name="**/*.properties" />
<include name="**/*.xml" />
</fileset>
</copy>
<delete dir="${project.dist.dir}" />
<mkdir dir="${project.dist.dir}" />
</target>
<target name="compileWithJavac" depends="prepare">
<echo message="compile with javac" />
<javac destdir="${project.target.dir}" srcdir="${project.src.dir}" source="1.8" target="1.8"
encoding="UTF-8" debug="true" includeantruntime="false">
<classpath refid="project.classpath" />
</javac>
</target>
<target name="package" depends="compileWithJavac">
<jar destfile="${project.dist.dir}/hello.jar">
<fileset dir="${project.target.dir}">
<include name="cn/aofeng/demo/java/lang/instrument/*.class" />
</fileset>
<manifest>
<attribute name="Premain-Class" value="cn.aofeng.demo.java.lang.instrument.FirstInstrumentation" />
</manifest>
</jar>
</target>
<target name="run" depends="package">
<java classname="cn.aofeng.demo.java.lang.instrument.Hello" fork="true">
<classpath refid="project.classpath" />
<classpath location="${project.target.dir}" />
<jvmarg value="-javaagent:${project.dist.dir}/hello.jar=&quot;Hello, Instrumentation&quot;" />
</java>
</target>
</project>

View File

@@ -0,0 +1,143 @@
package cn.aofeng.demo.java.lang.reflect;
import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* 通过反射获取类的构造方法、字段、方法和注解等信息。
*
* @author <a href="mailto:aofengblog@163.com">聂勇</a>
*/
public class ClassAnalyze {
final static String PREFIX = "==========";
final static String SUFFIX = PREFIX;
private static void parseClass(Class<?> claz) {
// 注解
parseAnnotation(claz);
// 类
StringBuilder buffer = new StringBuilder(32)
.append( Modifier.toString(claz.getModifiers()) )
.append(' ')
.append(claz.getName());
log(buffer.toString());
}
private static void parseConstructor(Constructor<?> c) {
// 注解
parseAnnotation(c);
// 构造方法
StringBuilder buffer = new StringBuilder(32)
.append( parseMember(c) )
.append('(');
// 参数
Class<?>[] params = c.getParameterTypes();
for (int index = 0; index < params.length; index++) {
buffer.append(params[index].getName());
if (index!=params.length-1) {
buffer.append(", ");
}
}
buffer.append(')');
log(buffer.toString());
}
private static void parseMethod(Method method) {
// 注解
parseAnnotation(method);
// 方法
StringBuilder buffer = new StringBuilder(32)
.append( parseMember(method) )
.append('(');
// 参数
Class<?>[] params = method.getParameterTypes();
for (int index = 0; index < params.length; index++) {
buffer.append(params[index].getName());
if (index!=params.length-1) {
buffer.append(", ");
}
}
buffer.append(')');
log(buffer.toString());
}
private static void parseField(Field field) {
// 注解
parseAnnotation(field);
// 字段
StringBuilder buffer = parseMember(field);
log(buffer.toString());
}
/**
* 解析方法、字段或构造方法的信息。
* @param member 方法、字段或构造方法
* @return 修饰符和名称组成的字符串。
*/
private static StringBuilder parseMember(Member member) {
StringBuilder buffer = new StringBuilder()
.append(Modifier.toString(member.getModifiers()))
.append(' ')
.append(member.getName());
return buffer;
}
/**
* 解析注解信息。
*/
private static void parseAnnotation(AnnotatedElement ae) {
Annotation[] ans = ae.getDeclaredAnnotations();
for (Annotation annotation : ans) {
log(annotation.toString());
}
}
public static void log(String msg, Object... param) {
System.out.println( String.format(msg, param) );
}
public static void main(String[] args) throws ClassNotFoundException {
if (args.length != 1) {
log("无效的输入参数!");
log("示例:");
log("java cn.aofeng.demo.java.lang.reflect.ClassAnalyze java.util.HashMap");
}
Class<?> claz = Class.forName(args[0]);
log("%s类%s", PREFIX, SUFFIX);
parseClass(claz);
log("%s构造方法%s", PREFIX, SUFFIX);
Constructor<?>[] cs = claz.getDeclaredConstructors();
for (Constructor<?> constructor : cs) {
parseConstructor(constructor);
}
log("%s字段%s", PREFIX, SUFFIX);
Field[] fields = claz.getDeclaredFields();
for (Field field : fields) {
parseField(field);
}
log("%s方法%s", PREFIX, SUFFIX);
Method[] methods = claz.getDeclaredMethods();
for (Method method : methods) {
parseMethod(method);
}
}
}

View File

@@ -0,0 +1,36 @@
package cn.aofeng.demo.java.lang.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import cn.aofeng.demo.util.LogUtil;
/**
* 通过反射使用构造方法创建对象实例。
*
* @author <a href="mailto:aofengblog@163.com">聂勇</a>
*/
public class CreateInstance {
public static void main(String[] args) throws InstantiationException, IllegalAccessException,
NoSuchMethodException, SecurityException,
IllegalArgumentException, InvocationTargetException {
Class<Man> claz = Man.class;
// 调用默认的public构造方法
Man man = claz.newInstance();
LogUtil.log(man.toString());
// 调用带参数的protected构造方法
Constructor<Man> manC = claz.getDeclaredConstructor(String.class);
man = manC.newInstance("aofeng");
LogUtil.log(man.toString());
// 调用带参数的private构造方法
manC = claz.getDeclaredConstructor(String.class, int.class);
manC.setAccessible(true);
man = manC.newInstance("NieYong", 32);
LogUtil.log(man.toString());
}
}

View File

@@ -0,0 +1,37 @@
package cn.aofeng.demo.java.lang.reflect;
import java.lang.reflect.Field;
import static cn.aofeng.demo.util.LogUtil.log;
/**
* 通过反射设置字段。
*
* @author <a href="mailto:aofengblog@163.com">聂勇</a>
*/
public class InvokeField {
public static void main(String[] args) throws NoSuchFieldException,
SecurityException, IllegalArgumentException, IllegalAccessException {
Man man = new Man();
Class<?> claz = man.getClass();
log("==========设置public字段的值==========");
log("height的值:%d", man.height);
Field field = claz.getField("height");
field.setInt(man, 175);
log("height的值:%d", man.height);
log("==========设置private字段的值==========");
log("power的值:%d", man.getPower());
field = claz.getDeclaredField("power");
field.setAccessible(true);
field.setInt(man, 100);
log("power的值:%d", man.getPower());
log("==========获取private字段的值==========");
int power = field.getInt(man);
log("power的值:%d", power);
}
}

View File

@@ -0,0 +1,84 @@
package cn.aofeng.demo.java.lang.reflect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import static cn.aofeng.demo.util.LogUtil.log;
/**
* 通过反射调用方法。
*
* @author <a href="mailto:aofengblog@163.com">聂勇</a>
*/
public class InvokeMethod {
/**
* 调用父类的方法。
*
* @param claz
* 类
* @param man
* 类对应的实例
*/
private static void invokeParentMethod(Class<Man> claz, Man man)
throws NoSuchMethodException, IllegalAccessException,
InvocationTargetException {
// 调用父类的public方法
Method method = claz.getMethod("setName", String.class);
method.invoke(man, "NieYong");
log(man.toString());
method = claz.getMethod("getName");
Object result = method.invoke(man);
log("name:%s", result);
// 调用父类的private方法
method = claz.getSuperclass().getDeclaredMethod("reset");
method.setAccessible(true);
result = method.invoke(man);
log(man.toString());
}
/**
* 调用自身的方法。
*
* @param claz
* 类
* @param man
* 类对应的实例
*/
private static void invokeSelfMethod(Class<Man> claz, Man man)
throws NoSuchMethodException, IllegalAccessException,
InvocationTargetException {
man.setName("XiaoMing");
// 调用自身的private方法
Method method = claz.getDeclaredMethod("setPower", int.class);
method.setAccessible(true);
method.invoke(man, 99);
log("power:%d", man.getPower());
// 调用自身的public方法
log("%s is marry:%s", man.getName(), (man.isMarry() ? "Yes" : "No"));
method = claz.getDeclaredMethod("setMarry", boolean.class);
method.invoke(man, true);
log("%s is marry:%s", man.getName(), (man.isMarry() ? "Yes" : "No"));
// 调用静态方法可将实例设置为null因为静态方法属于类
Man a = new Man("张三");
Man b = new Man("李四");
method = claz.getMethod("fight", Man.class, Man.class);
method.invoke(null, a, b); //
}
public static void main(String[] args) throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException,
InstantiationException {
Class<Man> claz = Man.class;
Man man = claz.newInstance();
invokeParentMethod(claz, man);
invokeSelfMethod(claz, man);
}
}

View File

@@ -0,0 +1,63 @@
package cn.aofeng.demo.java.lang.reflect;
import cn.aofeng.demo.json.gson.Person;
import cn.aofeng.demo.util.LogUtil;
/**
* 男人。
*
* @author <a href="mailto:aofengblog@163.com">聂勇</a>
*/
public class Man extends Person {
private boolean marry;
private int power;
public int height;
public Man() {
super();
LogUtil.log("%s的默认构造方法被调用", Man.class.getName());
}
protected Man(String name) {
super(name, 0);
LogUtil.log("%s带name参数的构造方法被调用", Man.class.getName());
}
@SuppressWarnings("unused")
private Man(String name, int age) {
super(name, age);
LogUtil.log("%s带name和age参数的构造方法被调用", Man.class.getName());
}
public static void fight(Man a, Man b) {
String win = "unkown";
if (a.power > b.power) {
win = a.getName();
} else if (b.power > a.power) {
win = a.getName();
}
LogUtil.log("%s vs %s, fight result:%s", a.getName(), b.getName(), win);
}
public boolean isMarry() {
return marry;
}
public void setMarry(boolean marry) {
this.marry = marry;
}
public int getPower() {
return power;
}
@SuppressWarnings("unused")
private void setPower(int power) {
this.power = power;
}
}

View File

@@ -0,0 +1,74 @@
package cn.aofeng.demo.java.lang.serialization;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
/**
* 自定义序列化和反序列化。
*
* @author <a href="mailto:aofengblog@163.com">聂勇</a>
*/
public class Man implements Externalizable {
private String manName;
private int manAge;
private transient String password;
public Man() {
// nothing
}
public Man(String name, int age) {
this.manName = name;
this.manAge = age;
}
public Man(String name, int age, String password) {
this.manName = name;
this.manAge = age;
this.password = password;
}
public String getManName() {
return manName;
}
public void setManName(String manName) {
this.manName = manName;
}
public int getManAge() {
return manAge;
}
public void setManAge(int manAge) {
this.manAge = manAge;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(manName);
out.writeInt(manAge);
out.writeObject(password);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
manName = (String) in.readObject();
manAge = in.readInt();
password = (String) in.readObject();
}
}

View File

@@ -0,0 +1,79 @@
package cn.aofeng.demo.java.lang.serialization;
import java.io.Serializable;
/**
* 默认序列化和
*
* @author <a href="mailto:aofengblog@163.com">聂勇</a>
*/
public class People implements Serializable {
private static final long serialVersionUID = 6235620243018494633L;
private String name;
private int age;
private transient String address;
private static String sTestNormal;
private static transient String sTestTransient;
public People(String name) {
this.name = name;
}
public People(String name, int age) {
this.name = name;
this.age = age;
}
public People(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getsTestNormal() {
return sTestNormal;
}
public void setsTestNormal(String sTestNormal) {
People.sTestNormal = sTestNormal;
}
public String getsTestTransient() {
return sTestTransient;
}
public void setsTestTransient(String sTestTransient) {
People.sTestTransient = sTestTransient;
}
}

View File

@@ -0,0 +1,126 @@
package cn.aofeng.demo.java.lang.serialization;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 关键字 transient 测试。
*
* @author <a href="mailto:aofengblog@163.com">聂勇</a>
*/
public class TransientDemo {
private static Logger _logger = LoggerFactory.getLogger(TransientDemo.class);
private String _tempFileName = "TransientDemo";
/**
* 将对象序列化并保存到文件。
*
* @param obj 待序列化的对象
*/
public void save(Object obj) {
ObjectOutputStream outs = null;
try {
outs = new ObjectOutputStream(
new FileOutputStream( getTempFile(_tempFileName) ));
outs.writeObject(obj);
} catch (IOException e) {
_logger.error("save object to file occurs error", e);
} finally {
IOUtils.closeQuietly(outs);
}
}
/**
* 从文件读取内容并反序列化成对象。
*
* @return {@link People}对象。如果读取文件出错 或 对象类型转换失败返回null。
*/
public <T> T load() {
ObjectInputStream ins = null;
try {
ins = new ObjectInputStream(
new FileInputStream( getTempFile(_tempFileName)) );
return ((T) ins.readObject());
} catch (IOException e) {
_logger.error("load object from file occurs error", e);
} catch (ClassNotFoundException e) {
_logger.error("load object from file occurs error", e);
} finally {
IOUtils.closeQuietly(ins);
}
return null;
}
private File getTempFile(String filename) {
return new File(getTempDir(), filename);
}
private String getTempDir() {
return System.getProperty("java.io.tmpdir");
}
private void displayPeople(People people) {
if (null == people) {
return;
}
String template = "People[name:%s, age:%d, address:%s, sTestNormal:%s, sTestTransient:%s]";
System.out.println( String.format(template, people.getName(), people.getAge(),
people.getAddress(), people.getsTestNormal(), people.getsTestTransient()));
}
private void displayMan(Man man) {
if (null == man) {
return;
}
String template = "Man[manName:%s, manAge:%d, password:%s]";
System.out.println( String.format(template, man.getManName(), man.getManAge(), man.getPassword()) );
}
/**
* @param args
*/
public static void main(String[] args) {
System.out.println(">>> Serializable测试");
TransientDemo demo = new TransientDemo();
People people = new People("张三", 30, "中国广州");
people.setsTestNormal("normal-first");
people.setsTestTransient("transient-first");
System.out.println("序列化之前的对象信息:");
demo.displayPeople(people);
demo.save(people);
// 修改静态变量的值
people.setsTestNormal("normal-second");
people.setsTestTransient("transient-second");
People fromLoad = demo.load();
System.out.println("反序列化之后的对象信息:");
demo.displayPeople(fromLoad);
System.out.println("");
System.out.println(">>> Externalizable测试");
Man man = new Man("李四", 10, "假密码");
System.out.println("序列化之前的对象信息:");
demo.displayMan(man);
demo.save(man);
Man manFromLoadMan = demo.load();
System.out.println("反序列化之后的对象信息:");
demo.displayMan(manFromLoadMan);
}
}