public class Test {
static int A = 10;
static {
A = 20;
}
}
class Test1 extends Test {
private static int B = A;
public static void main(String[] args) {
System.out.println(Test1.B);
}
}
//输出结果
//20
public interface InterfaceInitTest {
long A = CurrentTime.getTime();
}
interface InterfaceInitTest1 extends InterfaceInitTest {
int B = 100;
}
class InterfaceInitTestImpl implements InterfaceInitTest1 {
public static void main(String[] args) {
System.out.println(InterfaceInitTestImpl.B);
System.out.println("---------------------------");
System.out.println("当前时间:" InterfaceInitTestImpl.A);
}
}
class CurrentTime {
static long getTime() {
System.out.println("加载了InterfaceInitTest接口");
return System.currentTimeMillis();
}
}
//输出结果
//100
//---------------------------
//加载了InterfaceInitTest接口
//当前时间:1560158880660
public class MultiThreadInitTest {
static int A = 10;
static {
System.out.println(Thread.currentThread() "init MultiThreadInitTest");
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Runnable runnable = () -> {
System.out.println(Thread.currentThread() "start");
System.out.println(MultiThreadInitTest.A);
System.out.println(Thread.currentThread() "run over");
};
Thread thread1 = new Thread(runnable);
Thread thread2 = new Thread(runnable);
thread1.start();
thread2.start();
}
}
//输出结果
//Thread[main,5,main]init MultiThreadInitTest
//Thread[Thread-0,5,main]start
//10
//Thread[Thread-0,5,main]run over
//Thread[Thread-1,5,main]start
//10
//Thread[Thread-1,5,main]run over
public class StaticInnerSingleton {
/**
* 使用静态内部类实现单例:
* 1:线程安全
* 2:懒加载
* 3:非反序列化安全,即反序列化得到的对象与序列化时的单例对象不是同一个,违反单例原则
*/
private static class LazyHolder {
private static final StaticInnerSingleton INNER_SINGLETON = new StaticInnerSingleton();
}
private StaticInnerSingleton() {
}
public static StaticInnerSingleton getInstance() {
return LazyHolder.INNER_SINGLETON;
}
}
public class Tester {
static {
System.out.println("Tester类的静态初始化块");
}
}
class ClassLoaderTest {
public static void main(String[] args) throws ClassNotFoundException {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
//下面语句仅仅是加载Tester类
classLoader.loadClass("loader.Tester");
System.out.println("系统加载Tester类");
//下面语句才会初始化Tester类
Class.forName("loader.Tester");
}
}
//输出结果
//系统加载Tester类
//Tester类的静态初始化块
public class BootstrapTest {
public static void main(String[] args) {
//获取根类加载器所加载的全部URL数组
URL[] urLs = Launcher.getBootstrapClassPath().getURLs();
Arrays.stream(urLs).forEach(System.out::println);
}
}
//输出结果
//file:/C:/SorftwareInstall/java/jdk/jre/lib/resources.jar
//file:/C:/SorftwareInstall/java/jdk/jre/lib/rt.jar
//file:/C:/SorftwareInstall/java/jdk/jre/lib/sunrsasign.jar
//file:/C:/SorftwareInstall/java/jdk/jre/lib/jsse.jar
//file:/C:/SorftwareInstall/java/jdk/jre/lib/jce.jar
//file:/C:/SorftwareInstall/java/jdk/jre/lib/charsets.jar
//file:/C:/SorftwareInstall/java/jdk/jre/lib/jfr.jar
//file:/C:/SorftwareInstall/java/jdk/jre/classes
public class ClassloaderPropTest {
public static void main(String[] args) throws IOException {
//获取系统类加载器
ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader();
System.out.println("系统类加载器:" systemClassLoader);
/*
获取系统类加载器的加载路径——通常由CLASSPATH环境变量指定,如果操作系统没有指定
CLASSPATH环境变量,则默认以当前路径作为系统类加载器的加载路径
*/
Enumeration<URL> eml = systemClassLoader.getResources("");
while (eml.hasMoreElements()) {
System.out.println(eml.nextElement());
}
//获取系统类加载器的父类加载器,得到扩展类加载器
ClassLoader extensionLoader = systemClassLoader.getParent();
System.out.println("系统类的父加载器是扩展类加载器:" extensionLoader);
System.out.println("扩展类加载器的加载路径:" System.getProperty("java.ext.dirs"));
System.out.println("扩展类加载器的parant:" extensionLoader.getParent());
}
}
//输出结果
//系统类加载器:sun.misc.Launcher$AppClassLoader@18b4aac2
//file:/C:/ProjectTest/FengKuang/out/production/FengKuang/
//系统类的父加载器是扩展类加载器:sun.misc.Launcher$ExtClassLoader@1540e19d
//扩展类加载器的加载路径:C:\SorftwareInstall\java\jdk\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\ext
//扩展类加载器的parant:null
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
//第一步,先从缓存里查看是否已经加载
Class<?> c = findLoadedClass(name);
if (c == null) {
long t0 = System.nanoTime();
try {
//第二步,判断父加载器是否为null
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// ClassNotFoundException thrown if class not found
// from the non-null parent class loader
}
if (c == null) {
//第三步,如果前面都没有找到,就会调用findClass方法
long t1 = System.nanoTime();
c = findClass(name);
// this is the defining class loader; record the stats
sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
sun.misc.PerfCounter.getFindClasses().increment();
}
}
if (resolve) {
resolveClass(c);
}
return c;
}
}
public class Hello {
public void test(String str){
System.out.println(str);
}
}
public class MyClassloader extends ClassLoader {
/**
* 读取文件内容
*
* @param fileName 文件名
* @return
*/
private byte[] getBytes(String fileName) throws IOException {
File file = new File(fileName);
long len = file.length();
byte[] raw = new byte[(int) len];
try (FileInputStream fin = new FileInputStream(file)) {
//一次性读取Class文件的全部二进制数据
int read = fin.read(raw);
if (read != len) {
throw new IOException("无法读取全部文件");
}
return raw;
}
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class clazz = null;
//将包路径的(.)替换为斜线(/)
String fileStub = name.replace(".", "/");
String classFileName = fileStub ".class";
File classFile = new File(classFileName);
//如果Class文件存在,系统负责将该文件转换为Class对象
if (classFile.exists()) {
try {
//将Class文件的二进制数据读入数组
byte[] raw = getBytes(classFileName);
//调用ClassLoader的defineClass方法将二进制数据转换为Class对象
clazz = defineClass(name, raw, 0, raw.length);
} catch (IOException e) {
e.printStackTrace();
}
}
//如果clazz为null,表明加载失败,抛出异常
if (null == clazz) {
throw new ClassNotFoundException(name);
}
return clazz;
}
public static void main(String[] args) throws Exception {
String classPath = "loader.Hello";
MyClassloader myClassloader = new MyClassloader();
Class<?> aClass = myClassloader.loadClass(classPath);
Method main = aClass.getMethod("test", String.class);
System.out.println(main);
main.invoke(aClass.newInstance(), "Hello World");
}
}
//输出结果
//Hello World