mirror of
https://github.com/querydsl/querydsl.git
synced 2026-07-03 21:07:49 +08:00
Merge pull request #1673 from querydsl/i1668
Delay constant initialization via static inner class
This commit is contained in:
commit
00d5daf60a
@ -28,50 +28,53 @@ public final class ConstantImpl<T> extends ExpressionBase<T> implements Constant
|
||||
|
||||
private static final int CACHE_SIZE = 256;
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"}) //generic array creation not possible
|
||||
private static final Constant<Character>[] CHARACTERS = new Constant[CACHE_SIZE];
|
||||
private static class Constants {
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"}) //generic array creation not possible
|
||||
private static final Constant<Byte>[] BYTES = new Constant[CACHE_SIZE];
|
||||
@SuppressWarnings({"rawtypes", "unchecked"}) //generic array creation not possible
|
||||
private static final Constant<Character>[] CHARACTERS = new Constant[CACHE_SIZE];
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"}) //generic array creation not possible
|
||||
private static final Constant<Integer>[] INTEGERS = new Constant[CACHE_SIZE];
|
||||
@SuppressWarnings({"rawtypes", "unchecked"}) //generic array creation not possible
|
||||
private static final Constant<Byte>[] BYTES = new Constant[CACHE_SIZE];
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"}) //generic array creation not possible
|
||||
private static final Constant<Long>[] LONGS = new Constant[CACHE_SIZE];
|
||||
@SuppressWarnings({"rawtypes", "unchecked"}) //generic array creation not possible
|
||||
private static final Constant<Integer>[] INTEGERS = new Constant[CACHE_SIZE];
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"}) //generic array creation not possible
|
||||
private static final Constant<Short>[] SHORTS = new Constant[CACHE_SIZE];
|
||||
@SuppressWarnings({"rawtypes", "unchecked"}) //generic array creation not possible
|
||||
private static final Constant<Long>[] LONGS = new Constant[CACHE_SIZE];
|
||||
|
||||
private static final Constant<Boolean> FALSE = new ConstantImpl<Boolean>(Boolean.FALSE);
|
||||
@SuppressWarnings({"rawtypes", "unchecked"}) //generic array creation not possible
|
||||
private static final Constant<Short>[] SHORTS = new Constant[CACHE_SIZE];
|
||||
|
||||
private static final Constant<Boolean> TRUE = new ConstantImpl<Boolean>(Boolean.TRUE);
|
||||
private static final Constant<Boolean> FALSE = new ConstantImpl<Boolean>(Boolean.FALSE);
|
||||
|
||||
static {
|
||||
for (int i = 0; i < CACHE_SIZE; i++) {
|
||||
INTEGERS[i] = new ConstantImpl<Integer>(Integer.class, i);
|
||||
SHORTS[i] = new ConstantImpl<Short>(Short.class, (short) i);
|
||||
BYTES[i] = new ConstantImpl<Byte>(Byte.class, (byte) i);
|
||||
CHARACTERS[i] = new ConstantImpl<Character>(Character.class, (char) i);
|
||||
LONGS[i] = new ConstantImpl<Long>(Long.class, (long) i);
|
||||
private static final Constant<Boolean> TRUE = new ConstantImpl<Boolean>(Boolean.TRUE);
|
||||
|
||||
static {
|
||||
for (int i = 0; i < CACHE_SIZE; i++) {
|
||||
INTEGERS[i] = new ConstantImpl<Integer>(Integer.class, i);
|
||||
SHORTS[i] = new ConstantImpl<Short>(Short.class, (short) i);
|
||||
BYTES[i] = new ConstantImpl<Byte>(Byte.class, (byte) i);
|
||||
CHARACTERS[i] = new ConstantImpl<Character>(Character.class, (char) i);
|
||||
LONGS[i] = new ConstantImpl<Long>(Long.class, (long) i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Constant<Boolean> create(boolean b) {
|
||||
return b ? TRUE : FALSE;
|
||||
return b ? Constants.TRUE : Constants.FALSE;
|
||||
}
|
||||
|
||||
public static Constant<Byte> create(byte i) {
|
||||
if (i >= 0 && i < CACHE_SIZE) {
|
||||
return BYTES[i];
|
||||
if (i >= 0) {
|
||||
return Constants.BYTES[i];
|
||||
} else {
|
||||
return new ConstantImpl<Byte>(Byte.class, i);
|
||||
}
|
||||
}
|
||||
|
||||
public static Constant<Character> create(char i) {
|
||||
if (i >= 0 && i < CACHE_SIZE) {
|
||||
return CHARACTERS[i];
|
||||
if (i < CACHE_SIZE) {
|
||||
return Constants.CHARACTERS[i];
|
||||
} else {
|
||||
return new ConstantImpl<Character>(Character.class, i);
|
||||
}
|
||||
@ -79,7 +82,7 @@ public final class ConstantImpl<T> extends ExpressionBase<T> implements Constant
|
||||
|
||||
public static Constant<Integer> create(int i) {
|
||||
if (i >= 0 && i < CACHE_SIZE) {
|
||||
return INTEGERS[i];
|
||||
return Constants.INTEGERS[i];
|
||||
} else {
|
||||
return new ConstantImpl<Integer>(Integer.class, i);
|
||||
}
|
||||
@ -87,7 +90,7 @@ public final class ConstantImpl<T> extends ExpressionBase<T> implements Constant
|
||||
|
||||
public static Constant<Long> create(long i) {
|
||||
if (i >= 0 && i < CACHE_SIZE) {
|
||||
return LONGS[(int) i];
|
||||
return Constants.LONGS[(int) i];
|
||||
} else {
|
||||
return new ConstantImpl<Long>(Long.class, i);
|
||||
}
|
||||
@ -95,7 +98,7 @@ public final class ConstantImpl<T> extends ExpressionBase<T> implements Constant
|
||||
|
||||
public static Constant<Short> create(short i) {
|
||||
if (i >= 0 && i < CACHE_SIZE) {
|
||||
return SHORTS[i];
|
||||
return Constants.SHORTS[i];
|
||||
} else {
|
||||
return new ConstantImpl<Short>(Short.class, i);
|
||||
}
|
||||
|
||||
@ -33,7 +33,9 @@ import com.querydsl.core.types.Path;
|
||||
*/
|
||||
public abstract class DateExpression<T extends Comparable> extends TemporalExpression<T> {
|
||||
|
||||
private static final DateExpression<Date> CURRENT_DATE = currentDate(Date.class);
|
||||
private static class Constants {
|
||||
private static final DateExpression<Date> CURRENT_DATE = currentDate(Date.class);
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 6054664454254721302L;
|
||||
|
||||
@ -43,7 +45,7 @@ public abstract class DateExpression<T extends Comparable> extends TemporalExpre
|
||||
* @return current date
|
||||
*/
|
||||
public static DateExpression<Date> currentDate() {
|
||||
return CURRENT_DATE;
|
||||
return Constants.CURRENT_DATE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -33,9 +33,10 @@ import com.querydsl.core.types.Path;
|
||||
*/
|
||||
public abstract class DateTimeExpression<T extends Comparable> extends TemporalExpression<T> {
|
||||
|
||||
private static final DateTimeExpression<Date> CURRENT_DATE = currentDate(Date.class);
|
||||
|
||||
private static final DateTimeExpression<Date> CURRENT_TIMESTAMP = currentTimestamp(Date.class);
|
||||
private static class Constants {
|
||||
private static final DateTimeExpression<Date> CURRENT_DATE = currentDate(Date.class);
|
||||
private static final DateTimeExpression<Date> CURRENT_TIMESTAMP = currentTimestamp(Date.class);
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = -6879277113694148047L;
|
||||
|
||||
@ -45,7 +46,7 @@ public abstract class DateTimeExpression<T extends Comparable> extends TemporalE
|
||||
* @return current date
|
||||
*/
|
||||
public static DateTimeExpression<Date> currentDate() {
|
||||
return CURRENT_DATE;
|
||||
return Constants.CURRENT_DATE;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,7 +64,7 @@ public abstract class DateTimeExpression<T extends Comparable> extends TemporalE
|
||||
* @return current timestamp
|
||||
*/
|
||||
public static DateTimeExpression<Date> currentTimestamp() {
|
||||
return CURRENT_TIMESTAMP;
|
||||
return Constants.CURRENT_TIMESTAMP;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -34,8 +34,9 @@ public abstract class NumberExpression<T extends Number & Comparable<?>> extends
|
||||
|
||||
private static final long serialVersionUID = -5485902768703364888L;
|
||||
|
||||
@Nullable
|
||||
private static final NumberExpression<Double> random = Expressions.numberOperation(Double.class, MathOps.RANDOM);
|
||||
private static class Constants {
|
||||
private static final NumberExpression<Double> RANDOM = Expressions.numberOperation(Double.class, MathOps.RANDOM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@code max(left, right)} expression
|
||||
@ -67,7 +68,7 @@ public abstract class NumberExpression<T extends Number & Comparable<?>> extends
|
||||
* @return random()
|
||||
*/
|
||||
public static NumberExpression<Double> random() {
|
||||
return random;
|
||||
return Constants.RANDOM;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@ -33,7 +33,9 @@ public abstract class TimeExpression<T extends Comparable> extends TemporalExpre
|
||||
|
||||
private static final long serialVersionUID = 7360552308332457990L;
|
||||
|
||||
private static final TimeExpression<Time> CURRENT_TIME = currentTime(Time.class);
|
||||
private static class Constants {
|
||||
private static final TimeExpression<Time> CURRENT_TIME = currentTime(Time.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private transient volatile NumberExpression<Integer> hours, minutes, seconds, milliseconds;
|
||||
@ -107,7 +109,7 @@ public abstract class TimeExpression<T extends Comparable> extends TemporalExpre
|
||||
* @return current time
|
||||
*/
|
||||
public static TimeExpression<Time> currentTime() {
|
||||
return CURRENT_TIME;
|
||||
return Constants.CURRENT_TIME;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
package com.querydsl.core;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Collection;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.reflections.util.ClasspathHelper;
|
||||
|
||||
public class CycleClassInitDependencyTest {
|
||||
|
||||
private static ClassLoader loader;
|
||||
|
||||
@BeforeClass
|
||||
public static void overrideClassLoader() {
|
||||
loader = Thread.currentThread().getContextClassLoader();
|
||||
Collection<URL> urls = ClasspathHelper.forClassLoader();
|
||||
ClassLoader cl = URLClassLoader.newInstance(urls.toArray(new URL[urls.size()]), null/*no delegation*/);
|
||||
Thread.currentThread().setContextClassLoader(cl);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void resetClassLoader() {
|
||||
Thread.currentThread().setContextClassLoader(loader);
|
||||
}
|
||||
|
||||
@Test(timeout = 2000)
|
||||
public void test() throws InterruptedException {
|
||||
|
||||
// each thread wants to load one part of the dependency circle
|
||||
Thread t1 = new Thread(new LoadClassRunnable("com.querydsl.core.types.dsl.NumberExpression"));
|
||||
Thread t2 = new Thread(new LoadClassRunnable("com.querydsl.core.types.dsl.Expressions"));
|
||||
t1.start();
|
||||
t2.start();
|
||||
|
||||
t1.join();
|
||||
|
||||
}
|
||||
|
||||
private static class LoadClassRunnable implements Runnable {
|
||||
|
||||
private final String classToLoad;
|
||||
|
||||
public LoadClassRunnable(String classToLoad) {
|
||||
this.classToLoad = classToLoad;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
Class.forName(classToLoad, true, Thread.currentThread().getContextClassLoader());
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user