unsafehelper java_java 通过Unsafe不使用构造器直接创建对象

这里有一个User没有无参构造

public class User {

static {

System.out.println("static {}");

}

{

System.out.println("{}");

}

public User(String username, String password) {

this.username = username;

this.password = password;

}

private String username;

private String password;

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;

}

@Override

public String toString() {

return "User{" +

"username='" + username + '\'' +

", password='" + password + '\'' +

'}';

}

}

以下是创建User的三种方法

1.直接new一个User

User user = new User("zhangsan","123456");

2.使用反射则是

Constructor constructor = User.class.getConstructor(String.class, String.class);

User user = constructor.newInstance("zhangsan", "123456");

3.使用Unsafe

final Class> unsafeClass = Class.forName("sun.misc.Unsafe");

final Field theUnsafeField = unsafeClass.getDeclaredField("theUnsafe");

theUnsafeField.setAccessible(true);

final Object unsafe = theUnsafeField.get(null);

final Method allocateInstance = unsafeClass.getMethod("allocateInstance", Class.class);

User user = (User) allocateInstance.invoke(unsafe, User.class);

简单将Unsafe封装一个工具类

public final class UnsafeHelper {

private UnsafeHelper() {

}

private static final Object unsafe;

private static final Method allocateInstance;

static {

final Class> unsafeClass;

final Field theUnsafeField;

try {

unsafeClass = Class.forName("sun.misc.Unsafe");

} catch (ClassNotFoundException e) {

throw new UnsupportedOperationException("can't find sun.misc.Unsafe. " + e.getMessage(), e);

}

try {

theUnsafeField = unsafeClass.getDeclaredField("theUnsafe");

} catch (NoSuchFieldException e) {

throw new UnsupportedOperationException("can't find the field theUnsafe in sun.misc.Unsafe." + e.getMessage(), e);

}

theUnsafeField.setAccessible(true);

try {

unsafe = theUnsafeField.get(null);

} catch (IllegalAccessException e) {

throw new UnsupportedOperationException("get Unsafe instance failed: " + e.getMessage(), e);

}

try {

allocateInstance = unsafeClass.getMethod("allocateInstance", Class.class);

} catch (NoSuchMethodException e) {

throw new UnsupportedOperationException("can't find the method allocateInstance in sun.misc.Unsafe : " + e.getMessage(),

e);

}

}

public static T newInstance(Class> clazz) {

try {

return (T) allocateInstance.invoke(unsafe, clazz);

} catch (Exception e) {

throw new UnsupportedOperationException("create instance for " + clazz + " failed. " + e.getMessage(), e);

}

}

}

测试用例:

@Test(expected = InstantiationException.class)

public void newInstanceByReflect1() throws IllegalAccessException,

InstantiationException {

try {

User user = User.class.newInstance();

Assert.assertNull(user.getUsername());

} catch (Exception e) {

e.printStackTrace();

throw e;

}

}

@Test

public void newInstanceByReflect2() throws NoSuchMethodException, IllegalAccessException,

InvocationTargetException, InstantiationException {

Constructor constructor = User.class.getConstructor(String.class, String.class);

User user = constructor.newInstance("zhangsan", "123456");

System.out.println(user);

Assert.assertEquals("zhangsan", user.getUsername());

}

@Test

public void newInstanceByUnsafe() {

User user = UnsafeHelper.newInstance(User.class);

System.out.println(user);

Assert.assertNull(user.getUsername());

}

使用Gson提供的api来调用Unsafe

pom中添加依赖

com.google.code.gson

gson

2.8.5

InstanceHelper

import com.google.gson.internal.ConstructorConstructor;

import com.google.gson.internal.ObjectConstructor;

import com.google.gson.reflect.TypeToken;

import java.lang.reflect.Type;

import java.util.HashMap;

/**

* 无需构造器直接根据class创建实例

*

* @author Val Song

* @date 2018/10/17

* @since 1.0.0

*/

public final class InstanceHelper {

private InstanceHelper() {

}

private static ThreadLocal CONSTRUCTOR_CONSTRUCTOR_HOLDER =

ThreadLocal.withInitial(() -> new ConstructorConstructor(new HashMap<>(0)));

/**

* 不需要构造器创建实例,底层通过Unsafe实现

*

* @param type

* @param

* @return

*/

public static T newInstance(Type type) {

TypeToken typeToken = (TypeToken) TypeToken.get(type);

ObjectConstructor objectConstructor = CONSTRUCTOR_CONSTRUCTOR_HOLDER.get().get(typeToken);

return objectConstructor.construct();

}

}

InstanceHelper测试用例

@Test

public void newInstanceByGson() {

User user = InstanceHelper.newInstance(User.class);

System.out.println(user);

Assert.assertNull(user.getUsername());

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值