There are a couple of things you need to be aware of and keep straight.
first: str1, str2, p1 and p2 are REFERENCES to objects, not objects themselves. they are like address cards, whereas the objects themselves are like houses.
So, when you ask if "str1 and str2 are the same", do you mean "do they have the same address written on them" or do you mean, "Are the houses they refer to equivilent?" Obviously, if both have the same address then the houses are equivalent...but even if they have different addresses it is possible the houses are both worth the same amount.
Second: String literals are stored in the String Pool, as you know. However, when you say "new String(<whatever>)", that does create a String object that is NOT in the pool. From your example, "java" would be in the string pool, however, two new string are also created by the 'new' operator. So, str1 and str2 will point to different objects that are functionally equivalent. str1 == str2 is false, but str1.equals(str2) is true.
Finally, we don't know enough about the Person class to say. p1 and p2 will both point to different objects - that should be clear - so p1 == p2 is false. But without knowing how (or if) the equals() method is defined, we can't say much about p1.equals(p2).
There are only two hard things in computer science: cache invalidation, naming things, and off-by-one errors