public class Apple{ public static void main(String[] args){ System.out.println("Hello, Prettyprint!"); return true; } // hello comment }
Thursday, July 27, 2017
test
Minimize network traffics in Win10
#Step 1:
Disable win10 update service. (Pro / Enterprise Edition required)
#Step 2:
Download & open Firewall App Blocker (Fab) v1.6 .
#Step4:
Open the Wireshark, observe & record the DNS query traffics , then block those domain names queried by win10 or other apps in the ‘C:\WINDOWS\system32\drivers\etc\hosts’ file as follows:
# [start - Block m$]
127.0.0.1 win10.ipv6.microsoft.com
127.0.0.1 dns.msftncsi.com
127.0.0.1 client.wns.windows.com
127.0.0.1 c.urs.microsoft.com
127.0.0.1 v10.vortex-win.data.microsoft.com
127.0.0.1 www.msftconnecttest.com
127.0.0.1 v4ncsi.msedge.net
127.0.0.1 ncsi.4-c-0003.c-msedge.net
127.0.0.1 4-c-0003.c-msedge.net
127.0.0.1 travel.tile.appex.bing.com
127.0.0.1 cdn.content.prod.cms.msn.com
127.0.0.1 cdn.content.prod.cms.msn.com.edgekey.net
127.0.0.1 e10663.g.akamaiedge.net
127.0.0.1 iecvlist.microsoft.com
127.0.0.1 ie9comview.vo.msecnd.net
127.0.0.1 cs9.wpc.v0cdn.net
127.0.0.1 settings-win.data.microsoft.com
127.0.0.1 asimov-win.settings.data.microsoft.com.akadns.net
127.0.0.1 geo.settings.data.microsoft.com.akadns.net
127.0.0.1 hk2.settings.data.microsoft.com.akadns.net
127.0.0.1 go.microsoft.com
127.0.0.1 go.microsoft.com.edgekey.net
127.0.0.1 e11290.dspg.akamaiedge.net
127.0.0.1 displaycatalog.mp.microsoft.com
127.0.0.1 displaycatalog.md.mp.microsoft.com.akadns.net
127.0.0.1 displaycatalog-asia.md.mp.microsoft.com.akadns.net
127.0.0.1 hk2.displaycatalog.md.mp.microsoft.com.akadns.net
127.0.0.1 watson.telemetry.microsoft.com
127.0.0.1 modern.watson.data.microsoft.com.akadns.net
127.0.0.1 sway-cdn.com
127.0.0.1 cdn.onenote.net
127.0.0.1 weather.services.appex.bing.com
127.0.0.1 candycrushsoda.king.com
127.0.0.1 go.microsoft.com
127.0.0.1 www.bing.com ####
# [end - Block m$]
Disable win10 update service. (Pro / Enterprise Edition required)
#Step 2:
Download & open Firewall App Blocker (Fab) v1.6 .
Switch to the Whitelist Mode, add the applications you want to use to the whitelist.
#Step3:
Open windows firewall settings, add custom rules (e.g. add dns server, proxy server, gate to the allowlist/whitelist, block some LAN ip etc.), disable some default rules.#Step4:
Open the Wireshark, observe & record the DNS query traffics , then block those domain names queried by win10 or other apps in the ‘C:\WINDOWS\system32\drivers\etc\hosts’ file as follows:
# [start - Block m$]
127.0.0.1 win10.ipv6.microsoft.com
127.0.0.1 dns.msftncsi.com
127.0.0.1 client.wns.windows.com
127.0.0.1 c.urs.microsoft.com
127.0.0.1 v10.vortex-win.data.microsoft.com
127.0.0.1 www.msftconnecttest.com
127.0.0.1 v4ncsi.msedge.net
127.0.0.1 ncsi.4-c-0003.c-msedge.net
127.0.0.1 4-c-0003.c-msedge.net
127.0.0.1 travel.tile.appex.bing.com
127.0.0.1 cdn.content.prod.cms.msn.com
127.0.0.1 cdn.content.prod.cms.msn.com.edgekey.net
127.0.0.1 e10663.g.akamaiedge.net
127.0.0.1 iecvlist.microsoft.com
127.0.0.1 ie9comview.vo.msecnd.net
127.0.0.1 cs9.wpc.v0cdn.net
127.0.0.1 settings-win.data.microsoft.com
127.0.0.1 asimov-win.settings.data.microsoft.com.akadns.net
127.0.0.1 geo.settings.data.microsoft.com.akadns.net
127.0.0.1 hk2.settings.data.microsoft.com.akadns.net
127.0.0.1 go.microsoft.com
127.0.0.1 go.microsoft.com.edgekey.net
127.0.0.1 e11290.dspg.akamaiedge.net
127.0.0.1 displaycatalog.mp.microsoft.com
127.0.0.1 displaycatalog.md.mp.microsoft.com.akadns.net
127.0.0.1 displaycatalog-asia.md.mp.microsoft.com.akadns.net
127.0.0.1 hk2.displaycatalog.md.mp.microsoft.com.akadns.net
127.0.0.1 watson.telemetry.microsoft.com
127.0.0.1 modern.watson.data.microsoft.com.akadns.net
127.0.0.1 sway-cdn.com
127.0.0.1 cdn.onenote.net
127.0.0.1 weather.services.appex.bing.com
127.0.0.1 candycrushsoda.king.com
127.0.0.1 go.microsoft.com
127.0.0.1 www.bing.com ####
# [end - Block m$]
Wednesday, July 26, 2017
Overwriting vs. Appending the File in Java IO: FileOutputStream
Overwriting vs. Appending the File
When you create aFileOutputStream
pointing to a file that already exists, you can decide if you want to
overwrite the existing file, or if you want to append to the existing file. You decide that based on which of
the FileOutputStream
constructors you choose to use.
This constructor which takes just one parameter, the file name, will overwrite any existing file:
1 | OutputStream output = new FileOutputStream("c:\\data\\output-text.txt"); |
There is a constructor that takes 2 parameters too: The file name and a
boolean
. The boolean indicates
whether to append or overwrite an existing file. Here are two examples:1 2 3 4 | OutputStream output = new FileOutputStream("c:\\data\\output-text.txt", true); //appends to file OutputStream output = new FileOutputStream("c:\\data\\output-text.txt", false); //overwrites file |
@reference_1_tutorials.jenkov.com
Java IO: FileOutputStream
read(byte[]), mark() and reset() in Java IO: InputStream
read(byte[])
TheInputStream
class also contains two read()
methods which can read data from the
InputStream
's source into a byte
array. These methods are:
int read(byte[])
int read(byte[], int offset, int length)
read()
method.
The
read(byte[])
method will attempt to read as many bytes into the byte
array given as parameter
as the array has space for. The read(byte[])
method returns an int
telling how many
bytes were actually read. In case less bytes could be read from the InputStream
than the byte
array has space for, the rest of the byte
array will contain the same data as it did before the read
started. Remember to inspect the returned int to see how many bytes were actually read into the byte
array.
The
read(byte[], int offset, int length)
method also reads bytes into a byte
array,
but starts at offset
bytes into the array, and reads a maximum of length
bytes into
the array from that position. Again, the read(byte[], int offset, int length)
method returns
an int
telling how many bytes were actually read into the array, so remember to check this value
before processing the read bytes.
For both methods, if the end of stream has been reached, the method returns -1 as the number of bytes read.
Here is an example of how it could looke to use the
InputStream
's read(byte[])
method:
InputStream inputstream = new FileInputStream("c:\\data\\input-text.txt"); byte[] data = new byte[1024]; int bytesRead = inputstream.read(data); while(bytesRead != -1) { doSomethingWithData(data, bytesRead); bytesRead = inputstream.read(data); } inputstream.close();First this example create a
byte
array. Then it creates an int
variable named
bytesRead
to hold the number of bytes read for each read(byte[])
call, and
immediately assigns bytesRead
the value returned from the first read(byte[])
call.
Inside the
while
loop the doSomethingWithData()
method is called, passing along
the data
byte
array as well as how many bytes were read into the array as parameters.
At the end of the while
loop data is read into the byte
array again.
It should not take much imagination to figure out how to use the
read(byte[], int offset, int length)
method instead of read(byte[])
. You pretty much just replace the read(byte[])
calls
with read(byte[], int offset, int length)
calls.
mark() and reset()
TheInputStream
class has two methods called mark()
and reset()
which
subclasses of InputStream
may or may not support.
If an
InputStream
subclass supports the mark()
and reset()
methods, then
that subclass should override the markSupported()
to return true
. If the markSupported()
method returns false
then mark()
and reset()
are not supported.
The
mark()
sets a mark internally in the InputStream
which marks the point in the
stream to which data has been read so far. The code using the InputStream
can then continue reading
data from it. If the code using the InputStream
wants to go back to the point in the stream where
the mark was set, the code calls reset()
on the InputStream
. The InputStream
then "rewinds" and go back to the mark, and start returning (reading) data from that point again. This will of
course result in some data being returned more than once from the InputStream
.
The methods
mark()
and reset()
methods are typically used when implementing parsers.
Sometimes a parser may need to read ahead in the InputStream
and if the parser doesn't find what it
expected, it may need to rewind back and try to match the read data against something else.@reference_1_tutorials.jenkov.com
Java IO: InputStream
Tuesday, July 25, 2017
Checked Exceptions or Unchecked Exceptions
@reference_1_tutorials.jenkov.com
Checked or Unchecked Exceptions
Checked or Unchecked Exceptions
Catching Multiple Exceptions in Java 7
Before Java 7 you would write something like this:
In Java 7 you can catch multiple exceptions using the multi catch syntax:
@reference_1_tutorials.jenkov.com
Catching Multiple Exceptions in Java 7
try { // execute code that may throw 1 of the 3 exceptions below. } catch(SQLException e) { logger.log(e); } catch(IOException e) { logger.log(e); } catch(Exception e) { logger.severe(e); }As you can see, the two exceptions
SQLException
and IOException
are handled in the same way, but you still have to write two individual catch
blocks for them.In Java 7 you can catch multiple exceptions using the multi catch syntax:
try {
// execute code that may throw 1 of the 3 exceptions below.
} catch(SQLException | IOException e) {
logger.log(e);
} catch(Exception e) {
logger.severe(e);
}
Notice how the two exception class names in the first catch
block
are separated by the pipe character |
. The pipe character between exception class names
is how you declare multiple exceptions to be caught by the same catch
clause.
@reference_1_tutorials.jenkov.com
Catching Multiple Exceptions in Java 7
Exception thrown from try{} block & finally{} block, Try-Catch-Finally vs Try-with-resources
Try-Catch-Finally
private static void printFile() throws IOException {
InputStream input = null;
try {
input = new FileInputStream("file.txt");
int data = input.read();
while(data != -1){
System.out.print((char) data);
data = input.read();
}
} finally {
if(input != null){
input.close();
}
}
}
The code marked in bold is where the code can throw an Exception
. As you can see,
that can happen in 3 places inside the try
-block, and 1 place inside the finally
-block.
The
finally
block is always executed no matter if an exception is thrown from the try
block
or not. That means, that the InputStream
is closed no matter what happens in the try
block. Or, attempted closed that is. The InputStream
's close()
method may throw an
exception too, if closing it fails.
Imagine that an exception is thrown from inside the
try
block. Then the finally
block
is executed. Imagine then, that an exception is also thrown from the finally
block. Which exception
do you think is propagated up the call stack?
The exception thrown from the
finally
block would be propagated up the call stack, even if the
exception thrown from the try
block would probably be more relevant to propagate.( ///
If your code has a return statement inside the try or catch block, the code inside the finally-block will get executed before returning from the method.
No matter whether an exception is thrown or not inside the try or catch block the code inside the finally-block is executed.
Note: If an exception is thrown inside a finally block, and it is not caught, then that finally block is interrupted just like the try-block and catch-block is. That is why the previous example had the reader.close() method call in the finally block wrapped in a try-catch block:
} finally { if(reader != null){ try { reader.close(); } catch (IOException e) { //do something clever with the exception } } System.out.println("--- File End ---"); }That way the System.out.println("--- File End ---"); method call will always be executed. If no unchecked exceptions are thrown that is.
@reference_2_tutorials.jenkov.com
Basic try-catch-finally Exception Handling in Java
/// )
Try-with-resources
private static void printFileJava7() throws IOException {
try(FileInputStream input = new FileInputStream("file.txt")) {
int data = input.read();
while(data != -1){
System.out.print((char) data);
data = input.read();
}
}
}
When the try
block finishes the FileInputStream
will be closed
automatically. This is possible because FileInputStream
implements the
Java interface java.lang.AutoCloseable
. All classes implementing this
interface can be used inside the try-with-resources
construct.
If an exception is thrown both from inside the
try-with-resources
block,
and when the FileInputStream
is closed (when close()
is called),
the exception thrown inside the try
block is thrown to the outside world.
The exception thrown when the FileInputStream
was closed is suppressed.
This is opposite of what happens in the example first in this text, using the old style
exception handling (closing the resources in the finally
block).
@reference_1_tutorials.jenkov.com
Try-with-resources in Java 7
Using Multiple Resources
You can use multiple resources inside atry-with-resources
block and have
them all automatically closed. Here is an example:
private static void printFileJava7() throws IOException { try( FileInputStream input = new FileInputStream("file.txt"); BufferedInputStream bufferedInput = new BufferedInputStream(input) ) { int data = bufferedInput.read(); while(data != -1){ System.out.print((char) data); data = bufferedInput.read(); } } }This example creates two resources inside the parentheses after the
try
keyword.
An FileInputStream
and a BufferedInputStream
. Both of these resources
will be closed automatically when execution leaves the try
block.
The resources will be closed in reverse order of the order in which they are created / listed inside the parentheses. First the
BufferedInputStream
will be closed, then the FileInputStream
.
Monday, July 24, 2017
InputStream#read() return an int and not a byte or char?
End of Stream
If theread()
method returns -1, the end of stream has been reached, meaning there is no more data to read in the InputStream
. That is, -1 as int value, not -1 as byte or short value. There is a difference here!
When the end of stream has been reached, you can close the
InputStream
.
@reference_1_tutorials.jenkov.com
Java IO: InputStream
Answer1:
Because a
A more interesting question is why it doesn't return
Answer2:
/*
* 字节流和字符流的read()方法为什么返回的是int类型?而且为什么用-1作为判断是不是流末尾?
*/
package cn.itcast.day_16;
import Java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class ReadMethodDemo {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("src.txt");
fr.read();
/*
* 如果返回char, 那么无法表示流末尾.
* char的取值范围是从0到65535
* 这个范围内的所有字符, 都有可能在数据中出现
* 我们需要使用一个不可能在数据中出现的值来表示流末尾
* 那么Java中就是用-1来表示这个末尾的, 因为-1不会在数据中出现
* 而为了返回-1, 那么只能用int
* 当流中读取到一个字符时, read()方法内部就会当作int返回, 如果读到流末尾, 直接返回-1
*/
FileInputStream fis = new FileInputStream ("src.jpg");
//fis.read();
int b;
while((b = fis.read()) != -1)
System.out.println((byte)b); //打印的结果全是正数
/*
* 如果返回byte, 同样无法表示流末尾.
* byte的取值范围是从-128到127
* 这个范围内所有的数据, 都有可能在数据中出现
* read()方法需要返回一个特殊的值来表示流末尾, 这个值不能和流中的数据重复
*
* 字符流中读取到的char是直接当作int使用, 例如读取到一个'a'也就是97的时候, 那么就相当于返回了一个int的97
* 字节流中不能这么做, 因为如果文件中存在数据-1, 把-1直接当作int返回还是-1, 那么就无法区分这个读到的结果是流末尾还是流中的数据了
*
* read()方法内部将读取到的所有字节高位补0转为int返回, 这样做所有的数据都会是正数
* 这时就可以用-1表示流末尾了
* 而改变后的数据只要强转回byte, 就可以得到原有数据
*/
}
}
byte
can only hold -128 until 127, while it
should return 0 until 255 (and -1 when there's no byte left (i.e. EOF)).
Even if it returned byte
, there would be no room to represent EOF.A more interesting question is why it doesn't return
short
.Answer2:
It returns an int because when the stream can no longer be read, it returns -1.
If it returned a byte, then -1 could not be returned to indicate an error because -1 is a valid byte. In addition, you could not return value above 127 or below -128 because Java only handles signed bytes.
Many times when one is reading a file, you want the unsigned bytes for your processing code. To get values between 128 and 255 you could use a short, but by using an int you will align the memory registers with your data bus more efficiently. As a result, you don't really lose any information by using an int, and you probably gain a bit of performance. The only downside is the cost of the memory, but odds are you won't be hanging on to that int for long (as you will process it and turn it into a char or byte[]).
@reference_2_stackoverflow
Why does InputStream#read() return an int and not a byte?
If it returned a byte, then -1 could not be returned to indicate an error because -1 is a valid byte. In addition, you could not return value above 127 or below -128 because Java only handles signed bytes.
Many times when one is reading a file, you want the unsigned bytes for your processing code. To get values between 128 and 255 you could use a short, but by using an int you will align the memory registers with your data bus more efficiently. As a result, you don't really lose any information by using an int, and you probably gain a bit of performance. The only downside is the cost of the memory, but odds are you won't be hanging on to that int for long (as you will process it and turn it into a char or byte[]).
@reference_2_stackoverflow
Why does InputStream#read() return an int and not a byte?
Java doesn't have unsigned types.
why return type of read() is integer?read()
returns unsigned byte and the only way to represent it in Java is to use int
type.byte
values are in -128..127
range, while unsigned byte has values in 0..255
range.InputStream.read()
have to return 256 valid values + 1 invalid value as indication of end-of-stream. 257 values in total. Java's byte
can hold only 256 values. That is why they used int
: 0..255
represents valid byte values, -1
used for end-of-stream./*
* 字节流和字符流的read()方法为什么返回的是int类型?而且为什么用-1作为判断是不是流末尾?
*/
package cn.itcast.day_16;
import Java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
public class ReadMethodDemo {
public static void main(String[] args) throws IOException {
FileReader fr = new FileReader("src.txt");
fr.read();
/*
* 如果返回char, 那么无法表示流末尾.
* char的取值范围是从0到65535
* 这个范围内的所有字符, 都有可能在数据中出现
* 我们需要使用一个不可能在数据中出现的值来表示流末尾
* 那么Java中就是用-1来表示这个末尾的, 因为-1不会在数据中出现
* 而为了返回-1, 那么只能用int
* 当流中读取到一个字符时, read()方法内部就会当作int返回, 如果读到流末尾, 直接返回-1
*/
FileInputStream fis = new FileInputStream ("src.jpg");
//fis.read();
int b;
while((b = fis.read()) != -1)
System.out.println((byte)b); //打印的结果全是正数
/*
* 如果返回byte, 同样无法表示流末尾.
* byte的取值范围是从-128到127
* 这个范围内所有的数据, 都有可能在数据中出现
* read()方法需要返回一个特殊的值来表示流末尾, 这个值不能和流中的数据重复
*
* 字符流中读取到的char是直接当作int使用, 例如读取到一个'a'也就是97的时候, 那么就相当于返回了一个int的97
* 字节流中不能这么做, 因为如果文件中存在数据-1, 把-1直接当作int返回还是-1, 那么就无法区分这个读到的结果是流末尾还是流中的数据了
*
* read()方法内部将读取到的所有字节高位补0转为int返回, 这样做所有的数据都会是正数
* 这时就可以用-1表示流末尾了
* 而改变后的数据只要强转回byte, 就可以得到原有数据
*/
}
}
Java中字节流和字符流的read()方法为什么返回的值是int类型
Decorator Pattern for Java IO
InputStream
is an abstract class. Most concrete implementations like BufferedInputStream
, GzipInputStream
, ObjectInputStream
, etc. have a constructor that takes an instance of the same
abstract class. That's the recognition key of the decorator pattern
(this also applies to constructors taking an instance of the same
interface).When such a constructor is used, all methods will delegate to the wrapped instance, with changes in the way the methods behave. For example, buffering the stream in memory beforehand, decompressing the stream beforehand or interpreting the stream differently. Some even have additional methods that finally also delegate further to the wrapped instance. Those methods decorate the wrapped instance with extra behaviour.
Let's say that we have a bunch of serialized Java objects in a Gzipped file and that we want to read them quickly.
First open an inputstream of it:
FileInputStream fis = new FileInputStream("/objects.gz");
We want speed, so let's buffer it in memory:BufferedInputStream bis = new BufferedInputStream(fis);
The file is gzipped, so we need to ungzip it:GzipInputStream gis = new GzipInputStream(bis);
We need to unserialize those Java objects:ObjectInputStream ois = new ObjectInputStream(gis);
Now we can finally use it:SomeObject someObject = (SomeObject) ois.readObject();
// ...
The benefit is that you have a lot of freedom to decorate the stream
using one or more various decorators to suit your needs. That's much
better than having a single class for every possible combination like ObjectGzipBufferedFileInputStream
, ObjectBufferedFileInputStream
, GzipBufferedFileInputStream
, ObjectGzipFileInputStream
, ObjectFileInputStream
, GzipFileInputStream
, BufferedFileInputStream
, etc.Note that when you're about to close the stream, just closing the outermost decorator is sufficient. It will delegate the close call all the way to the bottom.
ois.close();
@reference_1_stackoverflowDecorator Pattern for IO
@reference_2_stackoverflow
Examples of GoF Design Patterns in Java's core libraries
Does it make sense to always wrap an InputStream as BufferedInputStream, when I know whether the given InputStream is something other than buffered?No.
It makes sense if you are likely to perform lots of small reads (one byte or a few bytes at a time), or if you want to use some of the higher level functionality offered by the buffered APIs; for example the
BufferedReader.readLine()
method.However, if you are only going to perform large block reads using the
read(byte[])
and / or read(byte[], int, int)
methods, wrapping the InputStream
in a BufferedInputStream
does not help. @reference_3_stackoverflow
Should I always wrap an InputStream as BufferedInputStream?
Friday, July 21, 2017
Retrieving a Website from Google Cache
(google search) -> site:[domain]
e.g. site:tutorials.jenkov.com
@reference_1_techattitude.com
How to download pages of a site from Google Cache
http://webcache.googleusercontent.com/search?q=cache:[domain]
e.g. http://webcache.googleusercontent.com/search?q=cache:tutorials.jenkov.com
@reference_2_cachedview.com
CachedView.com
The Google Cache Browser for any page on Internet.
@reference_3_stackoverflow
Retrieving an entire website using Google Cache?
@reference_4_guyrutenberg.com
Retrieving Google’s Cache for a Whole Website
e.g. site:tutorials.jenkov.com
@reference_1_techattitude.com
How to download pages of a site from Google Cache
http://webcache.googleusercontent.com/search?q=cache:[domain]
e.g. http://webcache.googleusercontent.com/search?q=cache:tutorials.jenkov.com
@reference_2_cachedview.com
CachedView.com
The Google Cache Browser for any page on Internet.
You can see what Google (still) knows about a website by using a
(In either case, you’d probably want to do some heavy-duty automating to fetch thousands of pages.)
site
restrict:http://www.google.com/search?q=site:[domain]
You might also check out the Internet Archive.(In either case, you’d probably want to do some heavy-duty automating to fetch thousands of pages.)
@reference_3_stackoverflow
Retrieving an entire website using Google Cache?
@reference_4_guyrutenberg.com
Retrieving Google’s Cache for a Whole Website
Tuesday, July 18, 2017
An anonymous class cannot have an explicitly declared constructor
@reference_0_tutorials.jenkov.com
Java Nested Classes
You can declare fields and methods inside an anonymous class, but you cannot declare a constructor. You can declare a static initializer for the anonymous class instead, though. Here is an example:
@reference_1_stackoverflow
Accessing constructor of an anonymous class
Answer 1:
From the Java Language Specification, section 15.9.5.1:
Answer 3:
@reference_2_stackoverflow
How to pass parameters to anonymous class?
Answer 1:
Answer 2:
Java Nested Classes
You can declare fields and methods inside an anonymous class, but you cannot declare a constructor. You can declare a static initializer for the anonymous class instead, though. Here is an example:
final Strint textToPrint = "Text..."; MyInterface instance = new MyInterface() { private String text; //static initializer { this.text = textToPrint; } public void doIt() { System.out.println(this.text); } }; instance.doIt();The same shadowing rules apply to anonymous classes as to inner classes.
@reference_1_stackoverflow
Accessing constructor of an anonymous class
Answer 1:
From the Java Language Specification, section 15.9.5.1:
An anonymous class cannot have an explicitly declared constructor.As an alternative, you can create some final local variables, and/or include an instance initializer in the anonymous class.
public class Test {
public static void main(String[] args) throws Exception {
final int fakeConstructorArg = 10;
Object a = new Object() {
{
System.out.println("arg = " + fakeConstructorArg);
}
};
}
}
Answer 2: ......
You can add an anonymous initializer like this:final int anInt = ...;
Object a = new Class1()
{
{
System.out.println(anInt);
}
void someNewMethod() {
}
};
Don't forget final on declarations of local variables or parameters used by the anonymous class, as i did it for anInt.Answer 3:
Here's another way around the problem:
public class Test{
public static final void main(String...args){
Thread t = new Thread(){
private String message = null;
Thread initialise(String message){
this.message = message;
return this;
}
public void run(){
System.out.println(message);
}
}.initialise(args[0]).start();
}
}
@reference_2_stackoverflow
How to pass parameters to anonymous class?
Answer 1:
Technically, no, because anonymous classes can't have constructors.
However, classes can reference variables from containing scopes. For an anonymous class these can be instance variables from the containing class(es) or local variables that are marked final.
edit: As Peter pointed out, you can also pass parameters to the constructor of the superclass of the anonymous class.
However, classes can reference variables from containing scopes. For an anonymous class these can be instance variables from the containing class(es) or local variables that are marked final.
edit: As Peter pointed out, you can also pass parameters to the constructor of the superclass of the anonymous class.
– Peter Lawrey
Feb 24 '11 at 17:08
Answer 2:
Yes, by adding an initializer method that returns 'this', and immediately calling that method:
No 'final' declaration needed.
int myVariable = 1;
myButton.addActionListener(new ActionListener() {
private int anonVar;
public void actionPerformed(ActionEvent e) {
// How would one access myVariable here?
// It's now here:
System.out.println("Initialized with value: " + anonVar);
}
private ActionListener init(int var){
anonVar = var;
return this;
}
}.init(myVariable) );
No 'final' declaration needed.
Create an instance of the Inner class (Non-static nested class)
Non-static nested classes in Java are also called inner classes. Inner classes are associated with an
instance of the enclosing class. Thus, you must first create an instance of the enclosing
class to create an instance of an inner class. Here is an example inner class definition:
@reference_1_tutorials.jenkov.com
Java Nested Classes
Java makes it possible though, for the
public class Outer { public class Inner { } }Here is how you create an instance of the
Inner
class:
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
@reference_1_tutorials.jenkov.com
Java Nested Classes
Inner Class Shadowing (Hiding?)
If a Java inner class declares fields or methods with the same names as field or methods in its enclosing class, the inner fields or methods are said to shadow over the outer fields or methods. Here is an example:public class Outer { private String text = "I am Outer private!"; public class Inner { private String text = "I am Inner private"; public void printText() { System.out.println(text); } } }In the above example both the
Outer
and Inner
class contains a field
named text
. When the Inner
class refers to text
it refers
to its own field. When Outer
refers to text
it also refers to its own field.
Java makes it possible though, for the
Inner
class to refer to the text
field of the
Outer
class. To do so it has to prefix the text
field reference with Outer.this.
(the outer class name + .this.
+ field name) like this:
public class Outer {
private String text = "I am Outer private!";
public class Inner {
private String text = "I am Inner private";
public void printText() {
System.out.println(text);
System.out.println(Outer.this.text);
}
}
}
Now the Inner.printText()
method will print both the Inner.text
and
Outer.text
fields.
Local Classes & 'final' local variables
Local Classes
Local classes in Java are like inner classes (non-static nested classes) that are defined inside a method or scope block ({ ... }
)
inside a method. Here is an example:
class Outer { public void printText() { class Local { } Local local = new Local(); } }Local classes can only be accessed from inside the method or scope block in which they are defined.
Local classes can access members (fields and methods) of its enclosing class just like regular inner classes.
Local classes can also access local variables inside the same method or scope block, provided these variables are declared
final
.
From Java 8 local classes can also access local variables and parameters of the method the local class is declared in. The parameter will have to be declared
final
or be effectually final. Effectually final means
that the variable is never changed after it is initialized. Method parameters are often effectually final.
Local classes can also be declared inside static methods. In that case the local class only has access to the static parts of the enclosing class. Local classes cannot contain all kinds of static declarations (constants are allowed - variables declared
static final
), because local classes are non-static
in nature - even if declared inside a static method.
The same shadowing rules apply for local classes as for inner classes.
An anonymous class can access members of the enclosing class. It can also access local variables which are declared final or effectively final (since Java 8).
@reference_1_tutorials.jenkov.com
Java Nested Classes
The methods in an anonymous class don't really have access to local variables and method parameters. Rather, when an object of the anonymous class is instantiated, copies of the final local variables and method parameters referred to by the object's methods are stored as instance variables in the object. The methods in the object of the anonymous class really access those hidden instance variables. [1]Thus, the local variables and method parameters accessed by the methods of the local class must be declared final to prevent their values from changing after the object is instantiated.
@reference_2_stackoverflow
Why Java inner classes require “final” outer instance variables?
@reference_3_developer.com
The Essence of OOP using Java, Anonymous Classes
In Java 8, where
final
can be implicit. Only an effectively final variable can be used in an anonymous inner class or lambda expression though.It's basically due to the way Java manages closures.
When you create an instance of an anonymous inner class, any variables which are used within that class have their values copied in via the autogenerated constructor. This avoids the compiler having to autogenerate various extra types to hold the logical state of the "local variables", as for example the C# compiler does... (When C# captures a variable in an anonymous function, it really captures the variable - the closure can update the variable in a way which is seen by the main body of the method, and vice versa.)
As the value has been copied into the instance of the anonymous inner class, it would look odd if the variable could be modified by the rest of the method - you could have code which appeared to be working with an out-of-date variable (because that's effectively what would be happening... you'd be working with a copy taken at a different time). Likewise if you could make changes within the anonymous inner class, developers might expect those changes to be visible within the body of the enclosing method.
Making the variable final removes all these possibilities - as the value can't be changed at all, you don't need to worry about whether such changes will be visible. The only ways to allow the method and the anonymous inner class see each other's changes is to use a mutable type of some description. This could be the enclosing class itself, an array, a mutable wrapper type... anything like that. Basically it's a bit like communicating between one method and another: changes made to the parameters of one method aren't seen by its caller, but changes made to the objects referred to by the parameters are seen.
If you're interested in a more detailed comparison between Java and C# closures, I have an article which goes into it further. I wanted to focus on the Java side in this answer :)
@reference_4_stackoverflow
Why are only final variables accessible in anonymous class?
An implicit copy of it is generated as the member of the inner class. Without declaring the local variable final, one could change it, leading to subtle errors due to the inner class still referring to the original value of that variable.
@reference_5_stackoverflow
Why a non-final “local” variable cannot be used inside an inner class, and instead a non-final field of the enclosing class can?
Monday, July 17, 2017
Hiding Fields & 'super' Keyword
Hiding Fields
Within a class, a field that has the same name as a field in the
superclass hides the superclass's field, even if their types are
different. Within the subclass, the field in the superclass cannot be
referenced by its simple name. Instead, the field must be accessed
through
@reference_1_docs.oracle.comsuper
, which is covered in the next section. Generally speaking, we don't recommend hiding fields as it makes code difficult to read.Using the Keyword super
Accessing Superclass Members
If your method overrides one of its superclass's methods, you can invoke the overridden method through the use of the keywordsuper
. You can also use super
to refer to a hidden field (although hiding fields is discouraged). Consider this class, Superclass
:public class Superclass { public void printMethod() { System.out.println("Printed in Superclass."); } }
Subclass
, that overrides printMethod()
:public class Subclass extends Superclass { // overrides printMethod in Superclass public void printMethod() { super.printMethod(); System.out.println("Printed in Subclass"); } public static void main(String[] args) { Subclass s = new Subclass(); s.printMethod(); } }
Subclass
, the simple name printMethod()
refers to the one declared in Subclass
, which overrides the one in Superclass
. So, to refer to printMethod()
inherited from Superclass
, Subclass
must use a qualified name, using super
as shown. Compiling and executing Subclass
prints the following:Printed in Superclass. Printed in Subclass
Subclass Constructors
The following example illustrates how to use thesuper
keyword to invoke a superclass's constructor. Recall from the
Bicycle
example that MountainBike
is a subclass of Bicycle
. Here is the MountainBike
(subclass) constructor that calls the superclass constructor and then adds initialization code of its own:public MountainBike(int startHeight, int startCadence, int startSpeed, int startGear) { super(startCadence, startSpeed, startGear); seatHeight = startHeight; }
The syntax for calling a superclass constructor is
super();
super(parameter list);
super()
, the superclass no-argument constructor is called. With super(parameter list)
, the superclass constructor with a matching parameter list is called.Note: If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass. If the super class does not have a no-argument constructor, you will get a compile-time error.
Object
does have such a constructor, so if Object
is the only superclass, there is no problem.
Object
. In fact, this is the case. It is called constructor chaining, and you need to be aware of it when there is a long line of class descent.Circular Reference in Javascript & Java
@reference_1_stackoverflow
Example of a circular reference in Javascript?
@reference_2_stackoverflow
How does Java Garbage Collection work with Circular References?
@reference_3_stackoverflow
Circular References in Java
Example of a circular reference in Javascript?
@reference_2_stackoverflow
How does Java Garbage Collection work with Circular References?
@reference_3_stackoverflow
Circular References in Java
Sunday, July 16, 2017
Overriding vs Hiding Java
keywords: Overriding / Hiding (Shadowing ) / run-time polymorphism / late binding / early binding
@reference_1_stackoverflow
Overriding vs Hiding Java - Confused
@reference_2_coderanch.com
Overriding Vs Hiding
@reference_1_docs.oracle.com
Overriding and Hiding Methods
If, however, the subclass calls up into a method in the superclass, and that method accesses the field with the same name as in the subclass, it is the field in the superclass that is accessed.
@reference_1_tutorials.jenkov.com
Java Inheritance
@reference_1_stackoverflow
Overriding vs Hiding Java - Confused
@reference_2_coderanch.com
Overriding Vs Hiding
@reference_1_docs.oracle.com
Overriding and Hiding Methods
Fields and Inheritance
As mentioned earlier, in Java fields cannot be overridden in a subclass. If you define a field in a subclass with the same name as a field in the superclass, the field in the subclass will hide (shadow) the field in the superclass. If the subclass tries to access the field, it will access the field in the subclass.If, however, the subclass calls up into a method in the superclass, and that method accesses the field with the same name as in the subclass, it is the field in the superclass that is accessed.
@reference_1_tutorials.jenkov.com
Java Inheritance
The difference between a.getClass() and A.class in Java
a.getClass()
returns the runtime type ofa
. I.e., if you haveA a = new B();
thena.getClass()
will return theB
class.A.class
evaluates to theA
class statically, and is used for other purposes often related to reflection.
What is the difference between a.getClass() and A.class in Java?
@reference_2_docs.oracle.com
Retrieving Class Objects
@reference_3_coderanch.com
Overriding Vs Hiding
Foo f = new Bar();
f.getClass().getMethod("classMethod", new Class[]).invoke(null, new Object[]);
Thursday, July 6, 2017
Upstart & Systemd in ubuntu
Ubuntu 14.04 uses Upstart instead of Systemd, so systemctl commands will not work. This changed in 15.04
@reference_1_stackoverflow
How to use systemctl in Ubuntu 14.04
@reference_1_stackoverflow
How to use systemctl in Ubuntu 14.04
Wednesday, July 5, 2017
setTimeout(..., 0)
Question: What does the following code print?
A:
one
three
two
console.log('one');
setTimeout(function() {
console.log('two');
}, 0);
console.log('three');
@reference_1_githubone
three
two
add - Currying
Question: How would you make this work?
add(2, 5); // 7
add(2)(5); // 7
@reference_1_github.com
A:
function add_(a){
return function(b){
return a + b;
};
}
function add(a){
var acc = 0;
var sub = function(b){
if(b === undefined)
return acc;
else if(!isNaN(b))
acc += b;
return sub;
};
return sub(a);
}
@reference_2_codeburst.io
return function(b){
return a + b;
};
}
function add(a){
var acc = 0;
var sub = function(b){
if(b === undefined)
return acc;
else if(!isNaN(b))
acc += b;
return sub;
};
return sub(a);
}
@reference_2_codeburst.io
Calling a Constructor From a Constructor & Calling Constructors in Superclasses
Calling a Constructor From a Constructor
In Java it is possible to call a constructor from inside another constructor. When you call a constructor from inside another constructor, you use thethis
keyword to refer to the constructor. Here is an
example of calling one constructor from within another constructor in Java:
public class Employee {
private String firstName = null;
private String lastName = null;
private int birthYear = 0;
public Employee(String first,
String last,
int year ) {
firstName = first;
lastName = last;
birthYear = year;
}
public Employee(String first, String last){
this(first, last, -1);
}
}
Notice the second constructor definition. Inside the body of the constructor you find this Java statement:
this(first, last, -1);The
this
keyword followed by parentheses and parameters means that another constructor in the
same Java class is being called. Which other constructor that is being called depends on what parameters you
pass to the constructor call (inside the parentheses after the this
keyword). In this example it
is the first constructor in the class that is being called.
Calling Constructors in Superclasses
In Java a class can extend another class. When a class extends another class it is also said to "inherit" from the class it extends. The class that extends is called the subclass, and the class being extended is called the superclass. Inheritance is covered in more detail in my tutorial about inheritance in Java.A class that extends another class does not inherit its constructors. However, the subclass must call a constructor in the superclass inside one of the subclass constructors!
Look at the following two Java classes. The class Car extends (inherits from) the class Vehicle.
public class Vehicle { private String regNo = null; public Vehicle(String no) { this.regNo = no; } }
public class Car extends Vehicle {
private String brand = null;
public Car(String br, String no) {
super(no);
this.brand = br;
}
}
Notice the constructor in the Car class. It calls the constructor in the superclass using this Java statement:
super(no);Using the keyword
super
refers to the superclass of the class using the super
keyword.
When super
keyword is followed by parentheses like it is here, it refers to a constructor in the
superclass. In this case it refers to the constructor in the Vehicle class. Because Car extends Vehicle, the Car
constructors must all call a constructor in the Vehicle.@reference_1_jenkov.com
Java Constructors
Java constructor parameter (or local variable) has the same name as a field in the same class
A Java constructor parameter can have the same name as a field. If a constructor parameter has the same name as
a field, the Java compiler has problems knowing which you refer to. By default, if a parameter (or local variable)
has the same name as a field in the same class, the parameter (or local variable) "shadows"(override) for the field.
Look at this constructor example:
To signal to the Java compiler that you mean the fields of the Employee class and not the parameters, put the
Java Constructors
public class Employee { private String firstName = null; private String lastName = null; private int birthYear = 0; public Employee(String firstName, String lastName, int birthYear ) { firstName = firstName; lastName = lastName; birthYear = birthYear; } }Inside the constructor of the Employee class the
firstName
, lastName
and birthYear
identifiers now refer to the constructor parameters, not to the Employee fields with the same names. Thus,
the constructor now just sets the parameters equal to themselves. The Employee fields are never initialized.
To signal to the Java compiler that you mean the fields of the Employee class and not the parameters, put the
this
keyword and a dot in front of the field name. Here is how the Java constructor declaration from
before looks with that change:
public class Employee { private String firstName = null; private String lastName = null; private int birthYear = 0; public Employee(String firstName, String lastName, int birthYear ) { this.firstName = firstName; this.lastName = lastName; this.birthYear = birthYear; } }
@reference_1_jenkov.com
Java Constructors
Tuesday, July 4, 2017
Final Parameters in Java
Final Parameters
A Java method parameter can be declaredfinal
, just like a variable. The value of a final
parameter
cannot be changed. That is, if the parameter is a reference to an object, the reference cannot be changed,
but values inside the object can still be changed. Here is an example:
public void writeText(final String text1, final String text2) { System.out.print(text1); // read value of text1 parameter. System.out.print(text2); // read value of text2 parameter. }In this method example you cannot reassign the parameters
text1
and text2
to any
other String
s than the ones passed as parameters when the method was called.@reference_1_jenkov.com
Java Methods
'void' in Java
All methods in Java must be one return type. void tell's to the JVM that that specific method will not return anything.
@reference_1_stackoverflow
What does void do in java?
In Java, the constructor is not a method. It only has the name of the class and a specific visibility. If it declares that returns something, then it is not a constructor, not even if it declares that returns a
@reference_1_stackoverflow
java “void” and “non void” constructor
@reference_1_stackoverflow
What does void do in java?
In Java, the constructor is not a method. It only has the name of the class and a specific visibility. If it declares that returns something, then it is not a constructor, not even if it declares that returns a
void
. Note the difference here:
public class SomeClass {
public SomeClass() {
//constructor
}
public void SomeClass() {
//a method, NOT a constructor
}
}
Also, if a class doesn't define a constructor, then the compiler will automatically add a default constructor for you.@reference_1_stackoverflow
java “void” and “non void” constructor
highly repetitive code and documentation in Java
@reference_1_stackoverflow
Managing highly repetitive code and documentation in Java
Managing highly repetitive code and documentation in Java
Java Modifier
@reference_1_tutorialspoint
Java - Modifier Types
@reference_2_tutorialspoint
Java - Non Access Modifiers
@reference_3_tutorialspoint
Java - Access Modifiers
While it is not allowed to decrease accessibility of an overridden method, it is allowed to expand accessibility of an overridden method. For instance, if a method is assigned the default access modifier in the superclass, then it is allowed to assign the overridden method in the subclass the
The Java access modifiers
@reference_4_jenkov.com
Java Access Modifiers
why a class cannot be defined as protected?
Java - Modifier Types
@reference_2_tutorialspoint
Java - Non Access Modifiers
Access Control and Inheritance
The following rules for inherited methods are enforced −- Methods declared public in a superclass also must be public in all subclasses.
- Methods declared protected in a superclass must either be protected or public in subclasses; they cannot be private.
- Methods declared private are not inherited at all, so there is no rule for them.
@reference_3_tutorialspoint
Java - Access Modifiers
Access Modifiers and Inheritance
When you create a subclass of some class, the methods in the subclass cannot have less accessible access modifiers assigned to them than they had in the superclass. For instance, if a method in the superclass ispublic
then it must be public
in the subclass too, in case the subclass overrides the method. If a method
in the superclass is protected
then it must be either protected
or public
in the subclass.
While it is not allowed to decrease accessibility of an overridden method, it is allowed to expand accessibility of an overridden method. For instance, if a method is assigned the default access modifier in the superclass, then it is allowed to assign the overridden method in the subclass the
public
access modifier.Class Access Modifiers
It is important to keep in mind that the Java access modifier assigned to a Java class takes precedence over any access modifiers assigned to fields, constructors and methods of that class. If the class is marked with thedefault
access modifier, then no other class outside the same Java package can access that class,
including its constructors, fields and methods. It doesn't help that you declare these fields public
,
or even public static
.
The Java access modifiers
private
and protected
cannot be assigned to a class.
Only to constructors, methods and fields inside classes. Classes can only have the default (package) and public
access modifier assigned to them.
@reference_4_jenkov.com
Java Access Modifiers
why a class cannot be defined as protected?
Because it makes no sense.
Protected class member (method or variable) is just like package-private (default visibility), except that it also can be accessed from subclasses.
Since there's no such concept as 'subpackage' or 'package-inheritance' in Java, declaring class protected or package-private would be the same thing.
You can declare nested and inner classes as protected or private, though.
@reference_5_stackoverflow
why a class cannot be defined as protected?
@reference_6_quora.com
Why can't we declare class as protected in Java?
Protected class member (method or variable) is just like package-private (default visibility), except that it also can be accessed from subclasses.
Since there's no such concept as 'subpackage' or 'package-inheritance' in Java, declaring class protected or package-private would be the same thing.
You can declare nested and inner classes as protected or private, though.
@reference_5_stackoverflow
why a class cannot be defined as protected?
@reference_6_quora.com
Why can't we declare class as protected in Java?
Monday, July 3, 2017
java.lang.Object.equals & java.util.Arrays.equals & java.util.Arrays.deepEquals
Use
As to why
For arrays,
Often we really want value equality for arrays, of course, which is why
Now consider this snippet:
In contrast, here's what
On
It's worth noting the analogy between these two methods and what we've discussed so far with regards to nested arrays.
If you want
@reference_1_stackoverflow.com
deepEquals(Object[], Object[])
.
Returns true
if the two specified arrays are deeply equal to one another.
Since an int[]
is an instanceof Object
, an int[][]
is an instanceof Object[]
.As to why
Arrays.equals
doesn't "work" for two dimensional arrays, it can be explained step by step as follows:
For arrays, equals
is defined in terms of object identity
System.out.println(
(new int[] {1,2}).equals(new int[] {1,2})
); // prints "false"
This is because arrays inherit their equals
from their common superclass, Object
.Often we really want value equality for arrays, of course, which is why
java.util.Arrays
provides the static
utility method equals(int[], int[])
.System.out.println(
java.util.Arrays.equals(
new int[] {1,2},
new int[] {1,2}
)
); // prints "true"
Array of arrays in Java
- An
int[]
is aninstanceof Object
- An
int[][]
is aninstanceof Object[]
- An
int[][]
is NOT aninstanceof int[]
java.util.Arrays.equals
is "shallow"
Now consider this snippet:System.out.println(
java.util.Arrays.equals(
new int[][] {
{ 1 },
{ 2, 3 },
},
new int[][] {
{ 1 },
{ 2, 3 },
}
)
); // prints "false"
Here are the facts:- Each argument is an
Object[]
- The element at index 0 is an
int[] { 1 }
- The element at index 1 is an
int[] { 2, 3 }
.
- The element at index 0 is an
- There are two
Object[]
instances - There are four
int[]
instances
Arrays.equals(Object[], Object[])
overload. From the API:ReturnsNow it should be clear why the above snippet printstrue
if the two specified arrays ofObjects
are equal to one another. The two arrays are consideredequal
if both arrays contain the same number of elements, and all corresponding pairs of elements in the two arrays are equal. Two objectse1
ande2
are considered equal if(e1==null ? e2==null : e1.equals(e2))
.
"false"
; it's because the elements of the Object[]
arrays are not equal by the above definition (since an int[]
has its equals
defined by object identity).
java.util.Arrays.deepEquals
is "deep"
In contrast, here's what Arrays.deepEquals(Object[], Object[])
does:Returnstrue
if the two specified arrays are deeply equal to one another. Unlike theequals(Object[],Object[])
method, this method is appropriate for use with nested arrays of arbitrary depth.
System.out.println(
java.util.Arrays.deepEquals(
new int[][] {
{ 1 },
{ 2, 3 },
},
new int[][] {
{ 1 },
{ 2, 3 },
}
)
); // prints "true"
On Arrays.toString
and Arrays.deepToString
It's worth noting the analogy between these two methods and what we've discussed so far with regards to nested arrays.System.out.println(
java.util.Arrays.toString(
new int[][] {
{ 1 },
{ 2, 3 },
}
)
); // prints "[[I@187aeca, [I@e48e1b]"
System.out.println(
java.util.Arrays.deepToString(
new int[][] {
{ 1 },
{ 2, 3 },
}
)
); // prints "[[1], [2, 3]]"
Again, the reasoning is similar: Arrays.toString(Object[])
treats each element as an Object
, and just call its toString()
method. Arrays inherit its toString()
from their common superclass Object
.If you want
java.util.Arrays
to consider nested arrays, you need to use deepToString
, just like you need to use deepEquals
.@reference_1_stackoverflow.com
Java array reflection: isArray vs. instanceof
if(obj.getClass().isArray()) {}
andif(obj instanceof Object[]) {}
?In general, use the
instanceof
operator to test whether an object is an array.At the JVM level, the
instanceof
operator translates to a specific "instanceof" byte code, which is highly optimized in most JVM implementations.The reflective approach (
getClass().isArray()
) is compiled to two separate "invokevirtual"
instructions. The more generic optimizations applied by the JVM to
these may not be as fast as the hand-tuned optimizations inherent in the
"instanceof" instruction.There are two special cases: null references and references to primitive arrays.
A null reference will cause
instanceof
to result false
, while the isArray
throws a NullPointerException
.Applied to a primitive array, the
instanceof
yields false
unless the right-hand operand exactly matches the component type. In contrast, isArray()
will return true
for any component type.@reference_1-stackoverflow
Java array reflection: isArray vs. instanceof
Object o = new int[] { 1,2 };
System.out.println(o instanceof int[]); // prints "true"
How to see if an object is an array without using reflection?
Sunday, July 2, 2017
equals() & == in Java
String one = new String("abc");
String two = new String("def");
String three = new String("abc");
String four = new String("ABC");
String five = "abc";
String six = "abc";
System.out.println( one.equals(three)); // true
System.out.println( one == three ); // false
System.out.println( five == six ); // true
System.out.println( five.equals(six) ); // true
@reference_1_jenkov.com
equals 方法来自java.lang.Object 类。Object类中的equals方法是用来比较“地址”的
(1)对于字符串变量来说,使用“==”和“equals()”方法比较字符串时,其比较方法不同。
“==”比较两个变量本身的值,即两个对象在内存中的首地址。
“equals()”比较字符串中所包含的内容是否相同。
比如:
String s1,s2,s3 = "abc", s4 ="abc" ;
s1 = new String("abc");
s2 = new String("abc");
那么:
s1==s2 是 false //两个变量的内存地址不一样,也就是说它们指向的对象不一样,
故不相等。
s1.equals(s2) 是 true //两个变量的所包含的内容是abc,故相等。
注意(1):
如果: StringBuffer s1 = new StringBuffer("a");
StringBuffer s2 = new StringBuffer("a");
结果: s1.equals(s2) //是false
解释:StringBuffer类中没有重新定义equals这个方法 ,因此这个方法就来自Object类,而Object类中的equals方法是用来比较“地址”的,所以等于false.
注意(2):
对于s3和s4来说,有一点不一样要引起注意,由于s3和s4是两个字符串常量所生成的变量,其中所存放的内存地址是相等的,所以s3==s4是true(即使没有s3=s4这样一个赋值语句)
(加注:
More precisely, objects representing Java String literals are obtained from a constant String pool which the Java virtual machine keeps internally. That means, that even classes from different projects compiled separately, but which are used in the same application may share constant String objects. The sharing happens at runtime. It is not a compile time feature.
If you want to be sure that two String variables point to separate String objects, use the
)
(2)对于非字符串变量来说,"=="和"equals"方法的作用是相同的都是用来比较其对象在堆内存的首地址,即用来比较两个引用变量是否指向同一个对象。
比如:
class A
{
A obj1 = new A();
A obj2 = new A();
}
那么:obj1==obj2是false
obj1.equals(obj2)是false
但是如加上这样一句:obj1=obj2;
那么 obj1==obj2 是true
obj1.equals(obj2) 是true
用同样的方法分析,s1和s3所指向的对象不一样,内容也不一样,故标记(3)和(4)处运行结果是false。
再看看s4和s5,这两个引用变量所指向的对象的内容都是一样的(内容都是123),但是这两个对象是用new操作符创建处类的,是在内存中分配两块空间给这两个对象的,因而这两个对象的内存地址不一样,故事两个不同的对象,标记(5)处的s4 == s5 运行结果为false,但是内容一样,故标记(6)处的s4.equals(s5)运行结果为true。同理,s4和s6所指向的对象地址不同,内容也不相同。故标记(7)(8)处运行结果为false。
s1和s4分别指向两个不同的对象(之所以这样称呼,是因为这两个对象在内存中的地址不相同,故而对象不相同),故标记为(9)处的s1 == s4运行结果为false,而标记为(10)处的s1.equals(s4)运行结果为true.
解释:不错,如果在新类中被覆盖了equals方法,就可以用来比较内容的。但是在上面的例子中类Value并没有覆盖Object中的equals方法,而是继承了该方法,因此它就是被用来比较地址的,又v1和v2的所指向的对象不相同,故标记(1)处的v1.equals(v2)运行结果为false,标记为(2)处的v1 == v2运行结果也为false。
@reference_2_cnblogs.com
java中equals方法的用法以及==的用法(转)
String two = new String("def");
String three = new String("abc");
String four = new String("ABC");
String five = "abc";
String six = "abc";
System.out.println( one.equals(three)); // true
System.out.println( one == three ); // false
System.out.println( five == six ); // true
System.out.println( five.equals(six) ); // true
public boolean isValid(String value) {
return "123".equals(value);
}
Compared with value.equals("123"), "123".equals(value) actually has the advantage, that if value
is null
(does not point to a
String
object, but to nothing), this version will not result in a NullPointerException
. @reference_1_jenkov.com
equals 方法来自java.lang.Object 类。Object类中的equals方法是用来比较“地址”的
String类中重新定义了equals这个方法,比较的是值,而不是地址。
所以,equals方法对于字符串来说是比较内容的,而对于非字符串来说是比较其指向的对象是否相同的。
== 比较符也是比较指向的对象是否相同的,也就是对象在对内存中的的首地址。
对于基本类型的包装类型,比如Boolean、Character、Byte、Short、Integer、Long、Float、Double等的引用变量,==是比较地址的,而equals是比较内容的(加注: 也就是说重新定义了equals方法)。
有两种用法说明:所以,equals方法对于字符串来说是比较内容的,而对于非字符串来说是比较其指向的对象是否相同的。
== 比较符也是比较指向的对象是否相同的,也就是对象在对内存中的的首地址。
对于基本类型的包装类型,比如Boolean、Character、Byte、Short、Integer、Long、Float、Double等的引用变量,==是比较地址的,而equals是比较内容的(加注: 也就是说重新定义了equals方法)。
(1)对于字符串变量来说,使用“==”和“equals()”方法比较字符串时,其比较方法不同。
“==”比较两个变量本身的值,即两个对象在内存中的首地址。
“equals()”比较字符串中所包含的内容是否相同。
比如:
String s1,s2,s3 = "abc", s4 ="abc" ;
s1 = new String("abc");
s2 = new String("abc");
那么:
s1==s2 是 false //两个变量的内存地址不一样,也就是说它们指向的对象不一样,
故不相等。
s1.equals(s2) 是 true //两个变量的所包含的内容是abc,故相等。
注意(1):
如果: StringBuffer s1 = new StringBuffer("a");
StringBuffer s2 = new StringBuffer("a");
结果: s1.equals(s2) //是false
解释:StringBuffer类中没有重新定义equals这个方法 ,因此这个方法就来自Object类,而Object类中的equals方法是用来比较“地址”的,所以等于false.
注意(2):
对于s3和s4来说,有一点不一样要引起注意,由于s3和s4是两个字符串常量所生成的变量,其中所存放的内存地址是相等的,所以s3==s4是true(即使没有s3=s4这样一个赋值语句)
(加注:
String Literals as Constants or Singletons
If you use the same string (e.g."Hello World"
)
in other String variable declarations, the Java virtual machine may only create a single String instance in memory.
The string literal thus becomes a de facto constant or singleton.
The various different variables initialized to the same constant string will point to the same String instance in memory.
Here is a Java String constant / singleton example:
String myString1 = "Hello World"; String myString2 = "Hello World";In this case the Java virtual machine will make both
myString1
and myString2
point
to the same String object.
More precisely, objects representing Java String literals are obtained from a constant String pool which the Java virtual machine keeps internally. That means, that even classes from different projects compiled separately, but which are used in the same application may share constant String objects. The sharing happens at runtime. It is not a compile time feature.
If you want to be sure that two String variables point to separate String objects, use the
new
operator like this:
String myString1 = new String("Hello World"); String myString2 = new String("Hello World");Even though the value (text) of the two Java Strings created is the same, the Java virtual machine will create two different objects in memory to represent them.
)
(2)对于非字符串变量来说,"=="和"equals"方法的作用是相同的都是用来比较其对象在堆内存的首地址,即用来比较两个引用变量是否指向同一个对象。
比如:
class A
{
A obj1 = new A();
A obj2 = new A();
}
那么:obj1==obj2是false
obj1.equals(obj2)是false
但是如加上这样一句:obj1=obj2;
那么 obj1==obj2 是true
obj1.equals(obj2) 是true
关于equals与==的区别从以下几个方面来说:
(1) 如果是基本类型比较,那么只能用==来比较,不能用equals
比如:
public class TestEquals {
public static void main(String[] args)
{
int a = 3;
int b = 4;
int c = 3;
System.out.println(a == b);//结果是false
System.out.println(a == c);//结果是true
System.out.println(a.equals(c));//错误,编译不能通过,equals方法
//不能运用与基本类型的比较
}
}
(1) 如果是基本类型比较,那么只能用==来比较,不能用equals
比如:
public class TestEquals {
public static void main(String[] args)
{
int a = 3;
int b = 4;
int c = 3;
System.out.println(a == b);//结果是false
System.out.println(a == c);//结果是true
System.out.println(a.equals(c));//错误,编译不能通过,equals方法
//不能运用与基本类型的比较
}
}
(2) 对于基本类型的包装类型,比如Boolean、Character、Byte、Short、Integer、Long、Float、Double等的引用变量,==是比较地址的,而equals是比较内容的。比如:
public class TestEquals {
public static void main(String[] args)
{ Integer n1 = new Integer(30);
Integer n2 = new Integer(30);
Integer n3 = new Integer(31);
System.out.println(n1 == n2);//结果是false 两个不同的Integer对象,故其地址不同,
System.out.println(n1 == n3);//那么不管是new Integer(30)还是new Integer(31) 结果都显示false
System.out.println(n1.equals(n2));//结果是true 根据jdk文档中的说明,n1与n2指向的对象中的内容是相等的,都是30,故equals比较后结果是true
System.out.println(n1.equals(n3));//结果是false 因对象内容不一样,一个是30一个是31
}
}
这是Integer的实例,如果是其他的比如Double、Character、Float等也一样。
public class TestEquals {
public static void main(String[] args)
{ Integer n1 = new Integer(30);
Integer n2 = new Integer(30);
Integer n3 = new Integer(31);
System.out.println(n1 == n2);//结果是false 两个不同的Integer对象,故其地址不同,
System.out.println(n1 == n3);//那么不管是new Integer(30)还是new Integer(31) 结果都显示false
System.out.println(n1.equals(n2));//结果是true 根据jdk文档中的说明,n1与n2指向的对象中的内容是相等的,都是30,故equals比较后结果是true
System.out.println(n1.equals(n3));//结果是false 因对象内容不一样,一个是30一个是31
}
}
这是Integer的实例,如果是其他的比如Double、Character、Float等也一样。
(3) 注意:对于String(字符串)、StringBuffer(线程安全的可变字符序列)、StringBuilder(可变字符序列)这三个类作进一步的说明。
(a)首先,介绍String的用法,请看下面的实例:
public class TestEquals {
public static void main(String[] args) {
String s1 = "123";
String s2 = "123";
String s3 = "abc";
String s4 = new String("123");
String s5 = new String("123");
String s6 = new String("abc");
System.out.println(s1 == s2);//(1)true
System.out.println(s1.equals(s2));//(2)true
System.out.println(s1 == s3);//(3)false
System.out.println(s1.equals(s3));//(4)false
System.out.println(s4 == s5);//(5)false
System.out.println(s4.equals(s5));//(6)true
System.out.println(s4 == s6);//(7)false
System.out.println(s4.equals(s6));//(8)false
System.out.println(s1 == s4);//(9)false
System.out.println(s1.equals(s4));//(10)true
}
}
答案解释:s1与s2分别指向由字符串常量”123” 创建的对象,在常量池中,只有一个对象,内容为123,有两个引用s1和s2指向这个对象,故这两个引用变量所指向的地址是相同的,因而(1)处的运行结果为true,又因为s1.equals(s2)是比较s1和s2所指向的对象的内容是否相等,而我们知道这两个对象的内容都是字符串常量”123”,故标记(2)处的运行结果是true。
(a)首先,介绍String的用法,请看下面的实例:
public class TestEquals {
public static void main(String[] args) {
String s1 = "123";
String s2 = "123";
String s3 = "abc";
String s4 = new String("123");
String s5 = new String("123");
String s6 = new String("abc");
System.out.println(s1 == s2);//(1)true
System.out.println(s1.equals(s2));//(2)true
System.out.println(s1 == s3);//(3)false
System.out.println(s1.equals(s3));//(4)false
System.out.println(s4 == s5);//(5)false
System.out.println(s4.equals(s5));//(6)true
System.out.println(s4 == s6);//(7)false
System.out.println(s4.equals(s6));//(8)false
System.out.println(s1 == s4);//(9)false
System.out.println(s1.equals(s4));//(10)true
}
}
答案解释:s1与s2分别指向由字符串常量”123” 创建的对象,在常量池中,只有一个对象,内容为123,有两个引用s1和s2指向这个对象,故这两个引用变量所指向的地址是相同的,因而(1)处的运行结果为true,又因为s1.equals(s2)是比较s1和s2所指向的对象的内容是否相等,而我们知道这两个对象的内容都是字符串常量”123”,故标记(2)处的运行结果是true。
用同样的方法分析,s1和s3所指向的对象不一样,内容也不一样,故标记(3)和(4)处运行结果是false。
再看看s4和s5,这两个引用变量所指向的对象的内容都是一样的(内容都是123),但是这两个对象是用new操作符创建处类的,是在内存中分配两块空间给这两个对象的,因而这两个对象的内存地址不一样,故事两个不同的对象,标记(5)处的s4 == s5 运行结果为false,但是内容一样,故标记(6)处的s4.equals(s5)运行结果为true。同理,s4和s6所指向的对象地址不同,内容也不相同。故标记(7)(8)处运行结果为false。
s1和s4分别指向两个不同的对象(之所以这样称呼,是因为这两个对象在内存中的地址不相同,故而对象不相同),故标记为(9)处的s1 == s4运行结果为false,而标记为(10)处的s1.equals(s4)运行结果为true.
(4) 再看一种情况,先看一个例子(该例子是Java编程思想第三章的例子):
class Value
{
int i;
}
public class EqualsMethod2 {
public static void main(String[] args) {
Value v1 = new Value();
Value v2 = new Value();
v1.i = v2.i = 100;
System.out.println(v1.equals(v2));//(1)false
System.out.println(v1 == v2);//(2)false
}
}
运行结果疑问:乍一看结果,有点惊讶,为什么不是true呢,不是说equals方法是比较内容的吗?
class Value
{
int i;
}
public class EqualsMethod2 {
public static void main(String[] args) {
Value v1 = new Value();
Value v2 = new Value();
v1.i = v2.i = 100;
System.out.println(v1.equals(v2));//(1)false
System.out.println(v1 == v2);//(2)false
}
}
运行结果疑问:乍一看结果,有点惊讶,为什么不是true呢,不是说equals方法是比较内容的吗?
解释:不错,如果在新类中被覆盖了equals方法,就可以用来比较内容的。但是在上面的例子中类Value并没有覆盖Object中的equals方法,而是继承了该方法,因此它就是被用来比较地址的,又v1和v2的所指向的对象不相同,故标记(1)处的v1.equals(v2)运行结果为false,标记为(2)处的v1 == v2运行结果也为false。
@reference_2_cnblogs.com
java中equals方法的用法以及==的用法(转)
Subscribe to:
Posts (Atom)
new ArrayList(10) { }