public class SendValue{
public String str=
"6";
public static void main(String[] args) {
SendValue sv=
new SendValue();
sv.change(sv.str);
System.
out.println(sv.str);
}
public void change(String str) {
str=
"10";
}
}
Java中String类型变量是immutable(不可变的)。 尽管 change()方法中的str与sv.str都是新的对象实例成员变量值”6”的引用, 由于String类型的 不可变 性,change()方法中的str=”10”语句实际上是将传入的str副本引用指向了一个值为“10”的新的内存地址,但 原数据引用 sv.str的引用值(也就是“6”的内存地址) 并没有发生改变,因此sv.str指向的值仍旧为6.
System.
out.println(“
is ”+
100 +
5);
System.
out.println(
100 +
5 +“
is”);
System.
out.println(“
is ”+ (
100 +
5));
1.”is”说明后面的内容都会被强制转换为string,所以是最后结果是拼接起来的 2.100+5先得到105,然后与is拼接 3.先算括号内的
public class Test
{
public static Test t1 =
new Test();
{
System.
out.println(
"blockA");
}
static
{
System.
out.println(
"blockB");
}
public static void main(String[] args)
{
Test t2 =
new Test();
}
}
静态块:用static申明,JVM加载类时执行,仅执行一次 构造块:类中直接用{}定义,每一次创建对象时执行 执行顺序优先级:静态块>main()>构造块>构造方法 静态块按照申明顺序执行,先执行Test t1 = new Test(); 所有先输出blockA,然后执行静态块,输出blockB,最后执行main 方法中的Test t2 = new Test();输出blockA。
int i=
0
Integer j = new Integer(
0)
System
.out.println(i==j)
System
.out.println(j
.equals(i))
1、基本型和基本型封装型进行“==”运算符的比较,基本型封装型将会自动拆箱变为基本型后再进行比较,因此Integer(0)会自动拆箱为int类型再进行比较,显然返回true; 2、两个Integer类型进行“==”比较,如果其值在-128至127,那么返回true,否则返回false, 这跟Integer.valueOf()的缓冲对象有关,这里不进行赘述。 3、两个基本型的封装型进行equals()比较,首先equals()会比较类型,如果类型相同,则继续比较值,如果值也相同,返回true 4、基本型封装类型调用equals(),但是参数是基本类型,这时候,先会进行自动装箱,基本型转换为其封装类型,再进行3中的比较。
class CompareReference{
public static void main(String [] args){
float f=
42.0f;
float f1[]=
new float[
2];
long x=
42;
f1[
0]=
42.0f;
}
}
判断x==f1[
0]
java核心卷I中43页有如下表述:两个数值进行二元操作时,会有如下的转换操作: 如果两个操作数其中有一个是double类型,另一个操作就会转换为double类型。 否则,如果其中一个操作数是float类型,另一个将会转换为float类型。 否则,如果其中一个操作数是long类型,另一个会转换为long类型。 否则,两个操作数都转换为int类型。 故,x==f1[0]中,x将会转换为float类型。
public static void main(String[] args){
String s;
System.
out.print(
"s="+s);
}
由于String s没有初始化,代码不能编译通过。 成员变量有初始值,而局部变量没有初始值得。本体中的s定义在方法中所以为局部变量-没有初始值。变量没有初始值就使用了,编译通不过
public class TestClass {
private static void testMethod(){
System.
out.println(
"testMethod");
}
public static void main(String[] args) {
((TestClass)
null).testMethod();
}
}
静态的方法也是可以通过对象.来访问的,其次,null可以被强制类型转换成任意类型的对象,于是通过它来执行静态方法,就可以理解了。
public class Base
{
private String baseName =
"base";
public Base()
{
callName();
}
public void callName()
{
System.
out. println(baseName);
}
static class Sub extends Base
{
private String baseName =
"sub";
public void callName()
{
System.
out. println (baseName) ;
}
}
public static void main(String[] args)
{
Base b =
new Sub();
}
}
new Sub();在创造派生类的过程中首先创建基类对象,然后才能创建派生类。 创建基类即默认调用Base()方法,在方法中调用callName()方法,由于派生类中存在此方法,则被调用的callName()方法是派生类中的方法,此时派生类还未构造,所以变量baseName的值为null
Integer i01 =
59;
int i02 =
59;
Integer i03 =
Integer.valueOf(
59);
Integer i04 =
new Integer(
59)。
JVM中一个字节以下的整型数据会在JVM启动的时候加载进内存,除非用new Integer()显式的创建对象,否则都是同一个对象 所有只有i04是一个新对象,其他都是同一个对象。
boolean b=
true?
false:
true==
true?
false:
true;
System.
out.println(b);
== 优先级高于 三目运算符,先判断 true == true,此时返回为 true, 这时表达式为 boolean b = true?false:true?false:true 此时三目运算符从右向左执行,true?false:true,返回false 这时表达式为 boolean b = true?false:false; 结果为:boolean b = false ;
public abstract class MyClass
}
public abstract void
method(int a);
constInt = constInt +
5;
public int
method();
public abstract void anotherMethod()
A是抽象方法,抽象类可以包含抽象方法,也可以不包含,虽然A 方法名是method,与题目中的方法同名,但是参数不同,是重载方法 B 在类中不能constInt = constInt + 5; 方法中可以 C 的方法名与题目中的方法名相同,返回值不能作为重载的依据 D 抽象方法没有方法体
class A {
public int func1(
int a,
int b) {
return a - b;
}
}
class B extends A {
public int func1(
int a,
int b) {
return a + b;
}
}
public class ChildClass {
public static void main(String[] args) {
A a =
new B();
B b =
new B();
System.out.println(
"Result=" + a.func1(
100,
50));
System.out.println(
"Result=" + b.func1(
100,
50));
}
}
也就是编译时候,会看左边引用类型是否能正确编译通过,运行的时候是调用右边的对象的方法。编译时候会发现左边满足条件所以编译通过,运行时候又会调用右边也就是 class B 的方法,所以答案都是150。
向上转型: Person p = new Man() ; //向上转型不需要强制类型转化 向下转型: Man man = (Man)new Person() ; //必须强制类型转化
public class Spike
{
public static void main(String[] args)
{
Counter a =
new Counter();
System.
out.println(a.increment());
System.
out.println(a.anotherIncrement());
Counter b =
new Counter();
System.
out.println(b.increment());
}
}
class Counter
{
private static int count =
0;
public int increment()
{
return count++;
}
public int anotherIncrement()
{
return ++count;
}
}
return count++是先return再+1 return ++count是先+1再return
class A {
private String a = “aa”;
public boolean methodB() {
String b = “bb”;
final String c = “cc”;
}
}
a是类中的成员变量,存放在堆区 b、c都是方法中的局部变量,存放在栈区
数组的定义: 声明一个数组时,不能直接限定数组长度,只有在创建实例化对象时,才能对给定数组长度.。
public class Example{
String str=
new String(
"hello");
char[]ch={
'a',
'b'};
public static void main(String args[]){
Example ex=
new Example();
ex.change(ex.str,ex.ch);
System.
out.print(ex.str+
" and ");
System.
out.print(ex.ch);
}
public void change(String str,
char ch[]){
str=
"test ok";
ch[
0]=
'c';
}
}
因为String是被final修饰的类,所以本身的内容是不会改变的,相当于基本数据类型的值传递,在changge方法中给str赋值了“test”,相当于重新创建了一个string类型的变量
public class Test {
public int aMethod(){
static int i =
0;
i++;
return i;
}
public static void main(String args[]){
Test test =
new Test();
test.aMethod();
int j = test.aMethod();
System.
out.println(j);
}
}
Java中静态变量只能在类主体中定义,不能在方法中定义。 静态变量属于类所有而不属于方法。
嵌套内部类
import EnclosingOne.InsideOne
1.public class Enclosingone
2.{
3. public class InsideOne {}
4.
5.}
6.public class inertest
7.{
8. public static void main(
string[]args)
9. {
10. EnclosingOne eo =
new EnclosingOne();
11.
12. }
13.
14.}
答案:EnclosingOne.InsideOne ei=eo.
new InsideOne();
InsideOne ei=eo.
new InsideOne();
内部类其实和类的属性没什么区别,只是在声明的时候必须是Outer.Inner a,就像int a 一样,至于静态内部类和非静态内部类new的时候有点区别, Outer.Inner a=new Outer().new Inner()(非静态,先有Outer对象才能有属性)
Outer.Inner a=new Outer.Inner()要把Outer.Inner看成一部分,就像类变量一样
class Value{
public int i=
15;
}
public class Test{
public static void main(String argv[]){
Test t=
new Test( );
t.first( );
}
public void first( ){
int i=
5;
Value v=
new Value( );
v.i=
25;
second(v,i);
System.
out.println(v.i);
}
public void second(Value v,
int i){
i =
0;
v.i =
20;
Value val =
new Value( );
v = val;
System.
out.println(v.i+
" "+i);
}
}
Object 中euqals的源码如上。没有重写equals时,是直接用==判断的,而String中重写了equals方法。
public boolean equals(Object obj) {
return (
this == obj);
}
equals没重写时候和==一样,比较的是对象的地址,题中new 了两个对象,所以各自地址不一样,使用equals比较为false,但是string类型中的equals方法Java默认重写了,可以比较对象里的值;两个对象指向的同一个string成员变量里的值相同,所以eqauals比较也相同。
public class Square {
long width;
public Square(
long l) {
width = l;
}
public static void main(String arg[]) {
Square a, b, c;
a =
new Square(
42L);
b =
new Square(
42L);
c = b;
long s =
42L;
}
}
a = new Square(42L); b = new Square(42L); 这里new了两个对象,所以a,b不是同一个引用a!=b s的类型跟a,b不同类型,所以s!=a,s!=b c = b; 这里b,c是同一个对象的引用,所以b==c是true
链接:https:
来源:牛客网
public class Test {
public static void main(String[] args) {
StringBuffer a =
new StringBuffer(
"A");
StringBuffer b =
new StringBuffer(
"B");
operator(a, b);
System.
out.println(a +
"," + b);
}
public static void operator(StringBuffer x, StringBuffer y) {
x.append(y); y = x;
}
}
答案 AB B
public class Test2
{
public void add(Byte b)
{
b = b++;
}
public void test()
{
Byte a =
127;
Byte b =
127;
add(++a);
System.
out.print(a +
" ");
add(b);
System.
out.print(b +
"");
}
}
答案:a=-
128 b=
127
public void add(Byte b){ b=b++; } 这里涉及java的自动装包/自动拆包 Byte的首字母为大写,是类,看似是引用传递,但是在add函数内实现++操作,会自动拆包成byte值传递类型,所以add函数还是不能实现自增功能。也就是说add函数只是个摆设,没有任何作用。 Byte类型值大小为-128~127之间。 add(++a);这里++a会越界,a的值变为-128 add(b); 前面说了,add不起任何作用,b还是127
public static void main(String[]args)
throws Exception {
final Object obj =
new Object();
Thread t1 =
new Thread() {
public void run() {
synchronized (obj) {
try {
obj.wait();
System.out.println(
"Thread 1 wake up.");
}
catch (InterruptedException e) {
}
}
}
};
t1.start();
Thread.sleep(
1000);
Thread t2 =
new Thread() {
public void run() {
synchronized (obj) {
obj.notifyAll();
System.out.println(
"Thread 2 sent notify.");
}
}
};
t2.start();
}
答案:Thread
2 sent notify.
Thread
1 wake up
执行obj.wait();时已释放了锁,所以t2可以再次获得锁,然后发消息通知t1执行,但这时t2还没有释放锁,所以肯定是执行t2,然后释放锁,之后t1才有机会执行。
public class StringDemo{
private static final String MESSAGE=
"taobao";
public static void main(String [] args) {
String a =
"tao"+
"bao";
String b=
"tao";
String c=
"bao";
System.
out.println(a==MESSAGE);
System.
out.println((b+c)==MESSAGE);
}
}
答案:
true false
要注意两个问题: 1,字符串在java中存储在字符串常量区中 2,==判断的是对象引用是否是同一个引用,判断字符串相等要用equals方法 首先判断a==MESSAGE 同一份字符串常量在内存中只有一份,因此是同一地址,返回true 再次比较(b+c)==MESSAGE 这相当于 new String(b+c)==MESSAGE 这里new了一个String对象,所以返回false
class Base{
public Base(String s){
System.out.print(
"B");
}
}
public class Derived extends Base{
public Derived (String s) {
System.out.print(
"D");
}
public static void main(String[] args){
new Derived(
"C");
}
}
答案:编译出错
子类构造方法在调用时必须先调用父类的,由于父类没有无参构造,必须在子类中显式调用,修改子类构造方法如下即可: public Derived(String s){ super(“s”); System.out.print(“D”); }
Boolean flag =
false;
if (flag =
true)
{
System.
out.println(“
true”);
}
else
{
System.
out.println(“
false”);
}
Boolean修饰的变量为包装类型,初始化值为false,进行赋值时会调用Boolean.valueOf(boolean b)方法自动拆箱为基本数据类型,因此赋值后flag值为true,输出文本true。 flag=true,这里赋值并没有错,被自己误导了
public class Bground extends Thread{
public static void main(String argv[]){
Bground b =
new Bground();
b.run();
}
public void start(){
for(
int i=
0;i<
10;i++){
System.out.println(
"Value of i = "+i);
}
}
}
答案:编译通过,但无输出
首先继承Thread,然后调用run方法,bgroud并没有重写run方法,那么就是调用父类Thread的run方法,所以无输出。
public class TestObj{
public static void main(String[] args){
Object o=
new Object(){
public boolean
equals(Object obj){
return true;
}
};
System.
out.println(o.equals(“Fred”));
}
}
//重写了equals(),不管参数是什么,都是返回true
String str1 =
"hello";
String str2 =
"he" +
new String(
"llo");
System.
err.println(str1 == str2);
答案:
false
String str1 = “hello”;这里的str1指的是方法区的字符串常量池中的“hello”,编译时期就知道的; String str2 = “he” + new String(“llo”);这里的str2必须在运行时才知道str2是什么,所以它是指向的是堆里定义的字符串“hello”,所以这两个引用是不一样的。
public static void main(String args[]) {
List Listlist1 =
new ArrayList();
Listlist1.add(
0);
List Listlist2 = Listlist1;
System.
out.println(Listlist1.
get(
0) instanceof Integer);
System.
out.println(Listlist2.
get(
0) instanceof Integer);
}
答案:
true true
collection类型的集合(ArrayList,LinkedList)只能装入对象类型的数据,该题中装入了0,是一个基本类型,但是JDK5以后提供了自动装箱与自动拆箱,所以int类型自动装箱变为了Integer类型。编译能够正常通过。 将list1的引用赋值给了list2,那么list1和list2都将指向同一个堆内存空间。instanceof是Java中关键字,用于判断一个对象是否属于某个特定类的实例,并且返回boolean类型的返回值。显然,list1.get(0)和list2.get(0)都属于Integer的实例
class Two{
Byte x;
}
class PassO{
public static void main(String[] args){
PassO p=new PassO();
p.start();
}
void start(){
Two t=new Two();
System.out.print(t.x+””);
Two t2=fix(t);
System.out.print(t.x+” ” +t2.x);
}
Two fix(Two tt){
tt.x=42;
return tt;
}
}
答案:null 42 42
注意x是Byte类型,也就是byte的包装类型,属于引用类型。实例该类对象时,如果成员变量没有显示初始化那么Java默认初始化为null. 该题中引用类型t作为形参进行传递,形参的改变会改变实参的值,所以再次打印t.x时已经变为42了。