在开始正文之前,给写数据库文档设计的小伙伴推荐一下MySQL-Front这个软件,为我确实是省去很多繁琐的步骤。关于他的下载和使用可自行百度,网上有很多。
每天要进步一点点哦
1.记录一道常见面试题:
Integer和int的区别?
(1)Integer是包装类,int是基本数据类型(2)Integer默认值是null,而int默认值是0
什么是Integer的自动拆箱和装箱?
(1)自动拆箱:Integer-->int Interger.intValue()
(2)自动装箱:int-->Integer Integer.valueOf()
在自动装箱时对于值从–128到127之间的内存值会被重复使用,范围之外的值每次使用都要new一个对象
eg:
package com.oop;
public class TestInteger01 {
public static void main(String[] args) {
Integer t1=100;
Integer t2=100;
Integer t3=200;
Integer t4=200;
// 验证在-128-127之间调用的是同一对象
System.out.println(t1==t2);
System.out.println(t3==t4);
// 自动装箱
int a=100;
Integer integer = Integer.valueOf(a);
System.out.println(t1==integer);
// 自动拆箱
int i = t3.intValue();
}
}
true
false
true
2. JVM内存中的两大对象
在java中可以将对象分为两大体系:字节码对象和实例对象
字节码对象
(1)什么是字节码对象?
每个类在加载(将类读到内存)时都会创建一个字节码对象,且在JVM内存中时唯一的。此对象存储的是类的结构信息。
(2)字节码对象的获取方式?(常用方式有三种)
- 类名.class
- Class.forName("包名.类名")
- 类的实例对象.getClass();
eg1:字节码对象JVM中是唯一的
package com.oop;
public class TestObject01 {
public static void main(String[] args) throws Exception {
// 内存中的字节码对象只有一个,三种获取类的字节码对象的方式:
// 方式一 这里的?是指泛型通配符,方式二不可以替换,因为传递的是字符串,无法判断是否正确
Class<?> c1 = Object.class;
Class<?> c2 = Object.class;
System.out.println(c1);
System.out.println(c1 == c2);
// 方式二
Class<?> c3 = Class.forName("java.lang.Object");
System.out.println(c2 == c3);
//方式三
Class<?> c4 = new Object().getClass();
System.out.println(c3 == c4);
}
}
eg2:静态代码块在类加载时不一定执行
package com.oop;
//静态代码块是否在类加载时执行:不一定
class Object02{
static {
System.out.println("静态代码块执行");
}
}
public class TestObject02 {
public static void main(String[] args) throws Exception{
// 不执行
Class<?> c1=Object02.class;
// 执行
Class.forName("com.oop.Object02");
Class.forName("com.oop.Object02",
// 是否执行静态代码块
true,
获取系统默认的类加载器。时这个对象将类读到内存中
ClassLoader.getSystemClassLoader());
}
}
eg3:亲自尝试一下 看看你能发现什么?????
package com.oop;
import java.util.HashMap;
import java.util.Map;
class ClassObject02 {
// 构建就会执行类的构造方法和实例属性 解决方法一:(1)将map提前(2)将static去掉
static ClassObject02 instance = new ClassObject02();
static Map<String, Object> map = new HashMap<String, Object>();
public ClassObject02() {
map.put("key1", 100);
System.out.println(map);
}
}
public class TestObject03 {
public static void main(String[] args) throws ClassNotFoundException {
// 报空指针异常的原因
// 默认为true
Class.forName("com.oop.ClassObject02");
}
}
3. 类加载时不一定对执行静态代码块,是否执行取决于类加载方式
类加载分类:
(1)显示加载、隐式加载
(2)主动加载、被动加载
eg:一定要自己尝试哦,在这里我们也学习到在开发中尽量将代码段抽取成一个方法,方便以后调用。idea和eclipse中选中代码段生成方法的快捷键是shift+Alt+m,
package com.oop;
/**
* 类加载时不一定会执行静态代码块,是否执行取决于类加载方式
* 类加载分为:显示加载、隐式加载
* 主动加载、被动加载
* idea操作:(1)将选中代码自动生成方法的快捷键:shift+Alt+m
* (2)运行时显示JVM类加载过程:Edit Configurations-->-XX:+TraceClassLoading
* 查:类加载过程
*/
class ClassA{
static int a=20;
static {
System.out.println("ClassA static");
}
}
class ClassB extends ClassA{
static int b=10;
static {
System.out.println("ClassB static");
}
}
public class TestObject04 {
public static void main(String[] args) throws ClassNotFoundException {
// 显示加载和隐式加载
doMethod01();
// 主动加载和被动加载
doMethod02();
}
public static void doMethod02() {
/**
* 主动加载:ClassA和ClassB的静态代码块都会主动加载
*/
System.out.println(ClassB.b);
/**
* 被动加载:只有ClassA的静态代码块执行
*/
System.out.println(ClassB.a);
}
public static void doMethod01() throws ClassNotFoundException {
// 定义类加载器
ClassLoader loader = ClassLoader.getSystemClassLoader();
/**
* 隐式加载
*/
// 方式一:类加载时不会执行静态代码块
Class<?> c1 = ClassA.class;
ClassA classA = new ClassA(); //会执行静态代码块
/**
* 显示加载
*/
// 方式二:类加载时会执行静态代码块
Class.forName("com.oop.ClassA");
// 与方式二的区别是,可以通过boolean值选则是否在类加载时执行静态代码块
Class.forName("com.oop.ClassA",false,loader);
}
}
未完待续。。。。。。每天要坚持学习哦 🐖