java常见问题笔记

cmd 提示“找不到或无法加载主类​”?

1.环境变量配置不正确

检查修正即可

2.程序名和函数入口不一致

检查修正即可

3.程序中使用了包 :package

编译的时候使用命令: javac -d . ​Test.java (. 代表当前目录)代替 javac test.java

运行时使用命令:java packagename.Test   代替  java Test

String类是不可变的,一旦String对象被创建,就不能被改变!

列:String s="java"

     s="python"

第一条语句创建了一个内容为"Java"的String对象,并将其引用赋值给s。

第二条语句创建了一个内容为"python"的新String对象,并将其引用赋值给s。

但是 "java" 字符串对象依然存在,只是不能再被访问,因为变量s现在指向了新的对象。s 只是对象String 的一个引用。

两条语句执行后,内存中存在了两个String对象,一个对 String对象的引用s。

垃圾回收机制与finalize()方法

1、Java提供finalize()方法,垃圾回收器准备释放内存的时候,会先调用finalize()。

       (1).对象不一定会被回收。

       (2).垃圾回收不是析构函数。

       (3).垃圾回收只与内存有关。

       (4).垃圾回收和finalize()都是靠不住的,只要JVM还没有快到耗尽内存的地步,它是不会浪费时间进行垃圾回收的。

2、垃圾回收器:

       (1).在 Java 中,当你创建一个对象时,Java 虚拟机(JVM)为该对象分配内存、调用构造函数并开始跟踪你使用的对象。当你停止使用一个对象(就是说,当没有对该对象有效的引用时),JVM 通过垃圾回收器将该对象标记为释放状态。

       (2)当垃圾回收器将要释放一个对象的内存时,它调用该对象的finalize() 方法(如果该对象定义了此方法)。垃圾回收器以独立的低优先级的方式运行,只有当其他线程挂起等待该内存释放的情况出现时,它才开始运行释放对象的内存。(事实上,你可以调用System.gc() 方法强制垃圾回收器来释放这些对象的内存。)

        (3)在以上的描述中,有一些重要的事情需要注意。首先,只有当垃圾回收器释放该对象的内存时,才会执行finalize()。如果在 Applet 或应用程序退出之前垃圾回收器没有释放内存,垃圾回收器将不会调用finalize()。

3、finalize()方法的优缺点:

     (1)根据 Java 文档,finalize() 是一个用于释放非 Java 资源的方法。但是,JVM 有很大的可能不调用对象的finalize() 方法,因此很难证明使用该方法释放资源是有效的。

     (2)Java 1.1 通过提供一个System.runFinalizersOnExit() 方法部分地解决了这个问题。(不要将这个方法与 java1.0 中的System.runFinalizations() 方法相混淆。)不象System.gc() 方法那样,System.runFinalizersOnExit() 方法并不立即试图启动垃圾回收器。而是当应用程序或 Applet 退出时,它调用每个对象的finalize() 方法。

eclipse上maven插件的安装

1. 打开eclipse,菜单“Help”-“Install New Software...”

2. 在Work with 地址栏输入:http://download.eclipse.org/releases/neon  (注意:红字部分是eclipse对应的版本名称),稍等片刻:

3. 在filter框中输入maven便能定位要安装的插件

4. 选择“Collaboration”-“m2e - Maven Integration for Eclipse",并点击next按钮进行安装步骤。

5.安装完成重启eclipse,菜单:Window --> preferences ,输入maven,进入installations,添加本地安装的Maven运行时环境

static静态变量/静态方法

静态变量/方法属于类,施工用的,而不属于对象。

sychronized、volatile

sychronized:同步代码块、阻塞其它线程持有锁。(可以作用于代码块、方法、静态方法、类)

volatile:当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。

  volatile作用

  1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。

  2)禁止进行指令重排序。

并发编程中的三个概念

1、原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。(synchronized和Lock)

2、可见性:可见性是指当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看得到修改的值。(volatile)

3、有序性:即程序执行的顺序按照代码的先后顺序执行。(指令重排序不会影响单个线程的执行,但是会影响到线程并发执行的正确性。)

  在Java里面,可以通过volatile关键字来保证一定的“有序性”(具体原理在下一节讲述)。

  另外可以通过synchronized和Lock来保证有序性,很显然,

  synchronized和Lock保证每个时刻是有一个线程执行同步代码,

  相当于是让线程顺序执行同步代码,自然就保证了有序性。

  

  JAVA内置happens-before原则来保障执行的有序性。

要想并发程序正确地执行,必须要保证原子性、可见性以及有序性。只要有一个没有被保证,就有可能会导致程序运行不正确。

JAVA内存模型

Java内存模型规定所有的变量都是存在主存当中(类似于前面说的物理内存),每个线程都有自己的工作内存(类似于前面的高速缓存)。线程对变量的所有操作都必须在工作内存中进行,而不能直接对主存进行操作。并且每个线程不能访问其他线程的工作内存。

(在32位平台下,对64位数据的读取和赋值是需要通过两个操作来完成的,不能保证其原子性。)

JDK动态代理的实现原理

java.lang.reflect.Proxy:通过使用newProxyInstance方法来获取代理的实现类。

java.lang.reflect.InvocationHandler :提供了一个invoke方法,供实现类扩展需要的代码逻辑。如Spring AOP 中各种advice。

原文地址:https://www.cnblogs.com/ahguSH/p/7002225.html