]>
iEval git - unical.git/blob - gson/internal/UnsafeAllocator.java
2 * Copyright (C) 2011 Google Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com
.google
.gson
.internal
;
19 import java
.io
.ObjectInputStream
;
20 import java
.io
.ObjectStreamClass
;
21 import java
.lang
.reflect
.Field
;
22 import java
.lang
.reflect
.Method
;
25 * Do sneaky things to allocate objects without invoking their constructors.
28 * @author Jesse Wilson
30 public abstract class UnsafeAllocator
{
31 public abstract <T
> T
newInstance(Class
<T
> c
) throws Exception
;
33 public static UnsafeAllocator
create() {
35 // public class Unsafe {
36 // public Object allocateInstance(Class<?> type);
39 Class
<?
> unsafeClass
= Class
.forName("sun.misc.Unsafe");
40 Field f
= unsafeClass
.getDeclaredField("theUnsafe");
41 f
.setAccessible(true);
42 final Object unsafe
= f
.get(null);
43 final Method allocateInstance
= unsafeClass
.getMethod("allocateInstance", Class
.class);
44 return new UnsafeAllocator() {
46 @SuppressWarnings("unchecked")
47 public <T
> T
newInstance(Class
<T
> c
) throws Exception
{
48 return (T
) allocateInstance
.invoke(unsafe
, c
);
51 } catch (Exception ignored
) {
54 // try dalvikvm, pre-gingerbread
55 // public class ObjectInputStream {
56 // private static native Object newInstance(
57 // Class<?> instantiationClass, Class<?> constructorClass);
60 final Method newInstance
= ObjectInputStream
.class
61 .getDeclaredMethod("newInstance", Class
.class, Class
.class);
62 newInstance
.setAccessible(true);
63 return new UnsafeAllocator() {
65 @SuppressWarnings("unchecked")
66 public <T
> T
newInstance(Class
<T
> c
) throws Exception
{
67 return (T
) newInstance
.invoke(null, c
, Object
.class);
70 } catch (Exception ignored
) {
73 // try dalvikvm, post-gingerbread
74 // public class ObjectStreamClass {
75 // private static native int getConstructorId(Class<?> c);
76 // private static native Object newInstance(Class<?> instantiationClass, int methodId);
79 Method getConstructorId
= ObjectStreamClass
.class
80 .getDeclaredMethod("getConstructorId", Class
.class);
81 getConstructorId
.setAccessible(true);
82 final int constructorId
= (Integer
) getConstructorId
.invoke(null, Object
.class);
83 final Method newInstance
= ObjectStreamClass
.class
84 .getDeclaredMethod("newInstance", Class
.class, int.class);
85 newInstance
.setAccessible(true);
86 return new UnsafeAllocator() {
88 @SuppressWarnings("unchecked")
89 public <T
> T
newInstance(Class
<T
> c
) throws Exception
{
90 return (T
) newInstance
.invoke(null, c
, constructorId
);
93 } catch (Exception ignored
) {
97 return new UnsafeAllocator() {
99 public <T
> T
newInstance(Class
<T
> c
) {
100 throw new UnsupportedOperationException("Cannot allocate " + c
);
This page took 0.048825 seconds and 4 git commands to generate.