Java Interview 01

First, talk about your understanding of java

1, platform independence, a compiler running everywhere

2、GC

3, language features

4, object-oriented

5, class libraries

6, exception handling

 

Two, Java compiler how to do once run everywhere? (How do the platform-independent)

First, let's write a java program:

public class ByteCodeSimple {
    public static void main(String[] args) {
        int i = 1, j = 5;
        i++;
        ++j;
        System.out.println(i);
        System.out.println(j);
    }
}

First, let's use the javac command to compile this program:

You can get to see the corresponding ByteCodeSimple.class

After re-src directory, using java command with the package name to perform class file, we can see that his execution was in line with expectations.

How do we view it .class file, you can open the Idea, it can decompile automatically.

Here we use javap commands to decompile -c significance on behalf of the decompiled, if you want to help the query command, you can enter javap -help to search.

Compile once run everywhere how to achieve?

java file -.> class file

Java source code is first compiled into byte code, and then interpreted by the JVM for different platforms, the Java language does not need to be recompiled to run on different platforms when, in the implementation of Java Virtual Machine byte code to convert into bytecode platform-specific machine instructions.

 

Three, JVM how to load .class file

JVM最值得学习:jvm内存模型,GC

Class Loader(类加载器):依据特定格式,加载class文件到内存

Execution Engine(执行引擎):对命令进行解析。

Native Interface(本地方法借口):融合不同开发语言的原生库为Java所用。

Runtime Data Area(内存模型):JVM内存空间结构模型。

 

结论:首先是由ClassLoader加载.class文件,之后通过Execution Engine命令进行执行。

 

四、什么是反射?

首先新建一个Robot类

public class Robot {
    private String name;

    public void hello1(String content) {
        System.out.println(content + name);
    }

    private String hello2(String content) {
        return "hello2" + content + name;
    }
}

使用反射去调用Robot类中的方法:

public class ReflectSample {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        //根据类名获取Class对象
        Class rc = Class.forName("com.interview.reflect.Robot");
        //根据类类型,去创建Robot对象
        Robot robot = (Robot) rc.newInstance();
        //调用方法hello1
        robot.hello1("123");

        //这个方法可以获得道类内部的所有方法包含公有和私有方法,却不能获得器父类继承的方法,和接口实现的方法
        Method method = rc.getDeclaredMethod("hello2", String.class);
        //在反射私有方法时要设置这个方法的值为true
        method.setAccessible(true);
        //执行方法并获得返回值
        String result = (String) method.invoke(robot, "wzy");
        //输出结果
        System.out.println("result:" + result);

        //这个方法可以获取类内的公有方法,和父类继承公有的方法;
        Method method1 = rc.getMethod("hello1", String.class);
        //调用方法hello1
        method1.invoke(robot, "welcome");

        //获取私有成员变量
        Field name = rc.getDeclaredField("name");
        //设置允许方法私有属性
        name.setAccessible(true);
        //设置私有对象的值
        name.set(robot, "yuan");

        //调用hello1方法
        method1.invoke(robot, "123");
    }
}

运行结果:

五、谈谈ClassLoader

类从编译到执行的过程

编译器将Robot.java源文件编译为Robot.class字节码文件

ClassLoader将字节码转换为JVM中的Class<Robot>对象

JVM利用Class<Robot>对象实例化为Robot对象。

 

ClassLoader在Java中有着非常重要的作用,它主要工作在Class的装载的加载阶段,其主要作用是从系统外部获得Class的二进制数据流,它是Java的核心组件,所有的

Class都是由ClassLoader进行加载的,ClassLoader负责通过将Class文件里的二进制数据流装载进系统,让后交给java虚拟机进行连接、初始化等操作。

 

通过查看源码我们可以发现,ClassLoader是一个抽象类:

其中最重要的方法就是ClassLoader中的loadClass(String name)方法

我们还可以发现ClassLoader类当中有parent成员变量,是另一个ClassLoader说名ClassLoader的种类不止一种。

ClassLoader的种类:

BootStrapClassLoader:C++编写,加载核心库java.*

ExtClassLoader:Java编写,加载扩展库javax.*(用户看的到的ClassLoader)(C:\Java\jdk\jre\lib\ext;C:\Windows\Sun\Java\lib\ext)

AppClassLoader:Java编写,加载程序所在的目录

自定义ClassLoader:Java编写,定制加载

 

通过查看ExtClassLoader源码,可以看到它的class的加载路径,用到才会去加载

 我们对这个路径进行打印得到:

通过查看AppClassLoader源码,我们可以看到其对应的加载路径:

对这个路径进行打印,得到结果,其中就包含了我们项目本身的.class文件输出路径out.加载类路径(classpath)最重要的路径:E:\project\javabasic\out\production\javabasic;

 

实现自定义ClassLoader:

首先我们先创建一个类:

1 public class Wali {
2     static {
3         System.out.println("Hello Wali");
4     }
5 }

之后单独对这个类使用javac进行编译,而不通过IDE,注意这个Wali类中没有定义package,否则执行的时候需要带着包名

创建一个MyClassLoader类

 1 public class MyClassLoader extends ClassLoader {
 2     /**
 3      * 加载类的路径
 4      */
 5     private String path;
 6     /**
 7      * 类加载器的名称
 8      */
 9     private String classLoaderName;
10 
11     /**
12      * 定义构造方法
13      * @param path 加载类的路径
14      * @param classLoaderName 类加载器的名称
15      */
16     public MyClassLoader(String path, String classLoaderName) {
17         this.path = path;
18         this.classLoaderName = classLoaderName;
19     }
20 
21     /**
22      * 用于寻找类文件
23      * @param name
24      * @return
25      */
26     @Override
27     public Class findClass(String name) {
28         byte[] b = loadClassData(name);
29         return defineClass(name, b, 0, b.length );
30     }
31 
32     /**
33      * 将文件转换为字节流
34      * @param name
35      * @return
36      */
37     private byte[] loadClassData(String name) {
38         //拼接出文件的名字
39         name = path + "\\" + name + ".class";
40         InputStream in = null;
41         ByteArrayOutputStream bos = null;
42 
43         try {
44             in = new FileInputStream(name);
45             bos = new ByteArrayOutputStream();
46             int i = 0;
47             //对文件进行读取
48             while ((i = in.read()) != -1) {
49                 bos.write(i);
50             }
51         } catch (IOException e) {
52             e.printStackTrace();
53         } finally {
54             try {
55                 in.close();
56                 bos.close();
57             } catch (IOException e) {
58                 e.printStackTrace();
59             }
60         }
61         //返回字节数组
62         return bos.toByteArray();
63     }
64 }

MyClassLoader测试类:

1 public class MyClassLoaderChecker {
2     public static void main(String[] args) throws IllegalAccessException, InstantiationException {
3         MyClassLoader myClassLoader = new MyClassLoader("E:\\project\\javabasic\\src\\com\\interview\\reflect", "myClassLoader");
4         Class aClass = myClassLoader.findClass("Wali");
5         //创建对象触发执行静态块代码
6         Object o = aClass.newInstance();
7     }
8 }

运行结果:

 

Guess you like

Origin www.cnblogs.com/fengyun2019/p/11223457.html