java基础总结一--让大学生活不再迷茫

这是我的第一篇博客,目前学了很多技术,也通过这些技术做过一些项目,许多一看就懂相同简单的地方往往通过复制代码,当自己实际操作并才发现不是这样总是忘东忘西,从现在开始着重复习基础,丛头开始,往后也将持续更新博客,如果有误,还请指正!!

一:基础部分
1.jvm,jre,jdk三者的区别
jvm:英文名称(Java Virtual Machine)它就是java的虚拟机,也是最核心的部分,所有的java程序都会首先编译成class文件,交给jvm处理,然后经过jvm解释后交给操作系统,不过jvm也不能单独处理,需要调用lib类库,而jre包含lib类库,总之jvm屏蔽了java程序与操作系统间的联系,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码)就可以实现在不同平台上的运行这也是java跨平台性的体现,只要在需要运行java应用程序的操作系统上,先安装一个Java虚拟机(JVM Java Virtual Machine)即可。
由JVM来负责Java程序在该系统中的运行。-“一次运行,到处编译”

jre:(Java Runtime Environment,Java运行环境)运行基于Java语言编写的程序所不可缺少的运行环境,jre就像咱们的pc机你编写了一个win64的程序,也需要对应的系统帮我们运行,同样,我们编写java程序也需要jre,如果你只需要运行java程序只需装jre,你装了jre也自动装了jvm jre=jvm+lib(类库)

jdk:英文名称(Java Development Kit) 包括了Java运行环境(Java Runtime Envirnment),集成了jre和一些好用的Java工具(javac/java/jdb等)和Java基础的类库(即Java API 包括rt.jar)jdk中包含jre,在jdk的安装目录下有一个名为jre的目录,里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和 lib和起来就称为jre。

所以说你只需下载一个jdk就包含了你运行和编译java程序所必须的环境和工具。

2.配置环境变量path和classpath的作用是什么
path:配置操作系统中所执行的命令的路径
比如我在桌面有个有个java文件
需要通过 javac HelloWorld.java-编译成class文件
再通过 java HelloWorld运行class文件 那javac和java这两个命令从何而来,在你没有配置环境变量之前这两个命令是不可以用的,配置这个path就可以告诉我们命令在那个位置
在这里插入图片描述classpath:是配置class文件所在的目录,用于指定类搜索路径,JVM就是通过它来寻找该类的class类文件的。一般jdk1.8之后不需要再配置此项

3.java语言的三种技术架构
我们常常在想学了java以后到底能干什么,这里将java技术分为3个方向,可以根据个人喜欢选择不同方向,不过3者都有融会贯通的地方

javaSE: SE是为开发普通桌面和商务应用程序开发的解决方案,这是学习其他两者的基础。 例如:用java板的扫雷

javaEE: EE是为开发企业环境下的应用程序提供的一些解决方案,包含如Servelt,JSP等,主要针对于WEB应用程序开发。也就是网页开发。

javaME:开发嵌入式设备(冰箱,遥控器等)提供的解决方案,但是目前主流的手机开发都是Android和IOS,如果想学手机端开发将java基础学好,就可以去学android或IOS了

4.&是位运算符。&&是布尔逻辑运算符。
在运行上,&两边的条件都要判断(不管前面的是ture还是false),而&&先判断前面的,若为false,则后面的不再判断。

5.数据类型(2种)
(1)基本数据类型
整数类型:byte(1字节 8位 -128~127)short(2字节 16位),int(4字节 32位),long(8字节 64位)
浮点数类型:double(8字节 32位),float(4字节 64位)
字符类型:char(2字节 16位)
布尔类型:boolean(没有明确大小 1位)

整数字面量默认都为 int 类型,所以在定义的 long 型数据后面加 L或 l
浮点数在现实中是连续的,在计算机数据结构中是离散的,计算机内部表示浮点数是有误差的。
float保留8位有效数字,小数点后前7位是精确的;
double保留16位有效数字,小数点后15位是精确的。
Java语言的浮点型常量默认是double类型,声明float类型时需要在结尾加f或者F:
float f = 1.03f;//结尾必须加F或者f

(2)引用数据类型
接口,类,数组

5.强制类型转换
例子:

           byte a = (byte)500;   // 编译出错 Type mismatch: cannot convert from int to byte
		   byte a1=127;     //编译正确
		   byte c = 3;      // 编译正确
		   float b = 1.5f;   // 编译出错 Type mismatch: cannot convert from double to float
		   double b1=b;//编译正确
		   float cc= b1;//编译出错 Type mismatch: cannot convert from double to float
		

因为byte的范围取值位-128-127超过此范围都会编译出错  `
而float b=1.5 因为浮点数类型都默认为double,double不能自动转为float必须显示的强制转换 float cc=(float)不过会发生精度的缺失,数据不准确

低类型->高类型默认自动提升
高类型->低类型需要显示的强制转化

强制类型转换所带来的结果是可能会丢失精度,如果此数值尚在范围较小的类型数值范围内,对于整型变量精度不变,但如果超出范围较小的类型数值范围内,很可能出现一些意外情况。

例子:

public class Test1 {
	 public static void main(String[] args)
	 {
		   int a=223;
		   byte b=(byte)a;
		   System.out.println(b);
	 }

}
结果 :-33

理解这道题结果前提要知道 首先知道什么是原码,补码,反码
这里有比较详细的教程:
(https://blog.csdn.net/zl10086111/article/details/80907428)

我们都知道int类型 是32位,byte类型是8位且计算机技术都是利用补码进行计算的,正数的反码和补码都是其本身,负数为反码再+1。
223的二进制为:
24位0+1101 1111 byte类型只有8位 于是从高位开始舍弃,截断后剩下:1101 1111 由于二进制最最高位 1代表负数,0代表正数数 ,1101 1111为负,负数的补码符号位不变取反再+1 1010 0000—+1—>1010 0001计算得出为-33

6.java构造方法
构造方法和方法的类似之处在于它们都包含可执行代码,区别在于,只有当Java类实例化时才执行构造方法,也就是new。构造方法通常包含类属性初始化代码,从严格意义上说,构造方法并不是方法,因为它不会返回任何值。

7.static关键字和this关键字
在往后的学习中会经常用到,static分为静态变量和静态代码块,就像我们现在很火的共享经济,它能被所有人(类对象)一起使用,每一次的使用都可能会改变它的信息,
例子:
在这里插入图片描述
静态代码块的初始化在使用此类任何一项属性的时候开始

定义static变量需要考虑的因素:

1.对象的生命周期:static变量在内存中存一份,也可以叫为静态共享。声明static的变量在内存中一直存在,除非服务器重启,或者手动回收。

2.访问/操作是否会冲突:在多线程的环境下必须考虑到(后一个操作会不会覆盖前一个人的)。
很多时候,我们自己开发的web程序,用了static,自己测试没有问题,但是再找个人一起操作,就会出现意想不到的问题。

容易犯错的地方:
我们常常将数据库连接对象包装成一个静态变量通过静态方法返回,
private static final String URI=xxx
private static final String USER=xxx
private static final String PASSWORD=xxx
private static Connection conn=null;

 static {
	 
	 try {
		Class.forName("com.mysql.jdbc.Driver");
		conn=DriverManager.getConnection(URI,USER,PASSWORD);
		
	} catch (ClassNotFoundException | SQLException e) {
		// TODO 自动生成的 catch 块
		e.printStackTrace();
	}
	 
 }
 
 public static Connection getConnection()
 {
	 return conn;
 }
 public static void close(Connection conn) {
	if(conn!=null) {
		try {
			//将用过的连接归还到连接池中
			conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

而在多线程环境下,当一个用户操作完成后,开始关闭连接对象,而另一方还正在操作,则会出现异常,数据库连接已断开。
因为连接对象是静态的,在服务器中只存在一份,当一个用户释放了连接,另一个用户再使用,就出现异常了

this关键字
(1).this这个关键字其代表的就是当前对象中的成员变量或者方法,如我们熟知的getset方法
class Person
{
String name;
public void setName(String name)
{
this.name=name;
} 这里的this指当前Person类的全局属性name
}
(2).调用类的构造方法
public class Student { //定义一个类,类的名字为student。
public Student() { //定义一个方法,名字与类相同故为构造方法
this(“Hello!”);
}
public Student(String name) { //定义一个带形式参数的构造方法
}
} //通过构造方法参数个数和类型区别调用哪个构造方法
(3).返回当前对象引用
this关键字除了可以引用变量或者成员方法之外,还有一个重大的作用就是返回类的引用。如在代码中,可以使用return this,来返回某个类的引用。此时这个this关键字就代表类的名称

为什么静态成员、静态方法中不能用this和super关键字
如同上文static例子所说,this代表的是调用这个函数的对象的引用 我连对象都没有创建何来对象引用,静态方法成功加载后,对象还不一定存在。
super也是同理的,假设你想在静态方法中使用super,前提是当前父类对象存在 如下面的例子:

public class Test1 {
	
	 public static void main(String[] args)
	 {
		// Student student=new Student();
		 System.out.println(student.s());
	 }
}

class Person
{
	public (static) String s()
	{
		return "Person";  
	}
	
}
class Student extends Person
{
	public (static) String b()
	{
		
		return super.s();  
	}
	
} 

这样使用super,是可行的,并不是只限于构造方法中使用,在创建子类对象的同时父类对象也一起创建了,并且先于子类创建

但你当使用了static关键字修饰继承下来的方法 在测试方法中不用创建对象就调用了该方法,子类和父类对象都没有创建,那这个在super指的是什么?就报错了.

8.重载:
概念:在同一个类中,允许存在一个以上的同名函数,只要它们的参数个数或者参数类型不同即可。
特点:与返回值类型无关,只看参数列表(参数类型以及参数个数)。

9.单例模式
单利模式设计保证了类实例的唯一性,因为创建对象很耗内存,且控制资源的使用,防止并发访问下,对数据的污染。他又分飞懒汉式和饿汉式

/*
 * 单例模式 懒汉式
 */
public class Test2 {
	private static Test2 test2=null;
	
	private Test2(){}

	public static Test2 getInstance()
	{
		if(test2==null)
		{
			test2=new Test2();
		}
		return test2;
	}
  
}、、

使用private私有化构造方法,是为了防止外部实例化对象也就是不允许外部创建对象 懒汉式可以怎么理解,我的实例初始为空,懒得创建,只有当外部想得到我实例的时候它才去创建

/*
 * 单例模式 饿汉式
 */
public class Test2 {
	private static Test2 instance=new Test2();
	
	private Test2() {}
	
	public static Test2 getInstance()
	{
		return instance;
	}

}//饿汉式天生就是线程安全的

饿汉式在类初始化的时候就已经创建,不管三七二十一先创建再说

实际开发中需要考虑线程安全和效率问题,目前有3种方法

1.在getInstance()加同步(synchronized)

public static synchronized  Test2 getInstance()
	{
		return instance;
	}

有锁就有等待效率不高,在任何调用这个方法的时候,你都需要承受同步带来的性能开销。
然而同步只在第一次调用的时候才被需要,也就是单例类实例创建的时候,双重锁出现了

2.双重检查锁定

public static Test2  getInstance()
{
if(instance==null)
{
 synchronized(Test2.class){
 if(instance==null) {
 instance=new Test2();}
}
}
return instance; //不为空就直接返回
}

那第2个判断空有何意义
试想一下高并发下 ,两个线程A,B同时进入了第一个if,假设A抢到锁,new了一个实例出来,然后释放锁,同时B也进来,如果不判断空可能会再实例一个对象出来,这样单例就失去了意义

3.静态内部类

public class Singleton {  
    private static class LazyHolder {  
       private static final Singleton INSTANCE = new Singleton();  
    }  
    private Singleton (){}  
    public static final Singleton getInstance() {  
       return LazyHolder.INSTANCE;  
    }  
}  

这种方法比1,2都好即实现了线程安全也解决了效率问题

还有疑问参考 单例模式详解

今天的学习就到这了,其中借鉴了网上许多资料,这里我就不一 一列举了,往后也将继续更新,如果有误还望指正,加油坚持下去!

下一篇博客java基础总结二:
https://blog.csdn.net/weixin_43410352/article/details/87201024

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值