Why is PMF.java a 'final' class? - java

According to the App Engine docs, the PersistenceManagerFactory should only be created once in the application.
It provides this sample:
package guestbook;
import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManagerFactory;
public final class PMF {
private static final PersistenceManagerFactory pmfInstance =
JDOHelper.getPersistenceManagerFactory("transactions-optional");
private PMF() {}
public static PersistenceManagerFactory get() {
return pmfInstance;
}
}
Why does PMF.java have to be a "public final class" in addition to making the pmfInstance a "private static final" object?

Classes should be final unless there's a good reason for them not to be.
There is no use case in which one would want to inherit from the PMF, so it should be final.

PMF is a class that should not be instantiated, since it has no instance state or methods, it is strictly there to provide static methods and global state.
Item 4 in Effective Java provides this idiom, however it does not add that the class should be made final, as it would be impossible to subclass it anyway with a private constructor. And there it is explicitly recommended that the private constructor be documented to avoid exactly the confusion you are having.
In addition, this code sample is providing the Static Initialization workaround for double check locking.

Related

Use dynamic class name in private static final variable of a class

Consider and example as below:
public class LoggerTestClass {
private static final Logger LOGGER = Logger.getLogger(LoggerTestClass.class);
}
In above example parameter passed to getLogger method is hard coded i.e LoggerTestClass.class
Now every time I change the class name I have to change the getLogger method's parameter.
Any other way which will fetch the class name automatically, for example for non static variable we can add this.getClass()
You can use Lombok to achive it in a clean fashion. All you need to do is to put #Log on top of your class and it will give you a log object to work with.
Read more here
Bro,For the question,first of all,we need make clear some concept.
In java,if a identifier is a member of a class,and decorated by 'static' keyword,it's value is Decided in the compile phase.
If the 'final' keyword is added,the identifier is constant,it's value must have a initial value on it is declared.and the value can't be change in the java runtime.
And the interesting thing is, the static constent is only declared inside the class,it can be called 'Classname' + '.' ,but has no connection to the class context.if there's no context ,the identifier con't become dynamic.
I think if let the identifier become dynamic ,there are only two ways:
let the identifier become a variable.remove the 'final' key word.the code look like this:
class Test {
private static Logger LOGGER;
public Test() {
LOGGER = Logger.getLogger(getClass().getSimpleName());
}
}
The 'private' keyword is sufficient if you don't want other classes to access it.
Try the java dynamic proxy. it can change the class in java runtime.
Code happy ~
Welcome to talk with me~
Can you use java 9+? Then solution is pretty simple:
private static final Logger LOGGER = Logger.getLogger(MethodHandles.lookup().lookupClass());
As MethodHandles.lookup() creates lookup using caller class. (via Reflection.getCallerClass() but Reflection is internal API, so you need that additional method handle lookup step)

How to Inject a managed bean(non-static) into static method?

I am using Java CDI for bean lifecycle.
#Named
public class ManagedBeanClass{
...
public ManagedProfile getManagedProfile(){
return new ManagedProfile();//logic will goes here
}
}
For Example
public class sample1{
#Inject private ManagedBeanClass managedBeanClass;
...
public static boolean methodExample() throws Exception{
ManagedProfile managedProfile = managedBeanClass.getManagedProfile();
....
}
}
Try to Inject(#Inject) Managed bean into Static method ,it shows compaliaton error
Cannot make a static reference to the non-static field
managedBeanClass
Getting stuck with Context DI and Static Object lifecycle.
Help me resolve this thanks in advance.
The problem in your example code has nothing to do with CDI; You are trying to access a non-static field (managedBeanClass) from a static method. This is not possible in Java (neither with nor without CDI).
Also, static methods almost always point to a design problem (*). Having static methods like that make your program harder to test and harder to change / maintain. Try to come up with a design that does not need static methods at all...
So, the short answer is: Don't.
But if your really must have a static method here, you can use constructor injection and set a static field from the constructor. But beware: This is potentially dangerous, because every new instance would set the field again (which could cause race conditions and unexpected behaviour).
(See also: https://stackoverflow.com/a/22068572/10363398)
(*) With a few exceptions, like the methods in the Math class. But those are very small, pure functions that have no side-effects.

How are private members of a class accessed via member functions of the class on memory level?

class TestMemberOuter1{
private int data=30;
class Inner{
void msg(){System.out.println("data is "+data);}
}
void display(){
Inner in=new Inner();
in.msg();
}
public static void main(String args[]){
TestMemberOuter1 obj=new TestMemberOuter1();
obj.display();
}
}
Why innerclass is able to access private members of the outerclass ?
I want to know what implementation [ at the lower level (Maybe at memory level or java implementation specific or any other not sure)] enables to achieve this kind of behaviour in java .
I dont think neither you need any memory level modifictaion or logic implementation to achieve this nor I think java will have any huge code logic at memory level to implement the same.
Memory has got nothing to do with it. Private, public and protected are just a access filters, No matter whether it is a private, public or protected all these variables will reside in a same memory which is allocated for an object.
There is no differrent memory allocation for private, public or protected variables. They are all ultimately the properties of same object.
Then how come compiler handles this ???
Its bit simpler than that.
These access filters clearly informs in what context they should be allowed to access.
Private : Only whitin the class :) Whenever compiler sees the variable which is provate being accessed any where out side the class it will flag the error Thats all.
Protected : All class within the same package :) Whenever compiler sees the variable which is Protected being accessed any where out package it will flag the error Thats all.
Public : Access to all :) No flags.
Remember accessing variables outside context results in compiler error not runtime error ?? For the same reason.
You dont need a huge logic behind it, Just keep the list of private, protected and public variables and check their usage is appropriate or not thats all.
EDIT
As per your updated question "Why innerclass is able to access private members of the outerclass ?"
Drawing the conclusion from the same analogy I explained above, private variables are allowed to be accessed anywhere within the class.
Now where is your innerclass declared? As a part of your outer class itself isn't it. So when you access the private variable of outer class inside the inner class compiler has no issue with it, because your inner class itself resides inside the outer class.
I hope I made a little sense with my answer :) Happy coding.
Currently, inner classes are compiled into distinct class files, but the compiler will insert synthetic helper methods when there is an access to a private member across nested classes. The synthetic method itself will have package-private access and perform the access to the private member within its own class.
This can be demonstrated with private methods as their execution can be traced and will show the execution of these helper methods:
public class OuterClass {
static class InnerClass {
private static void test() {
OuterClass.privateMethod();
}
}
private static void privateMethod() {
Thread.dumpStack();
}
public static void main(String[] args) {
InnerClass.test();
}
}
Running this program will print:
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:1329)
at OuterClass.privateMethod(OuterClass.java:9)
at OuterClass.access$000(OuterClass.java:2)
at OuterClass$InnerClass.test(OuterClass.java:5)
at OuterClass$InnerClass.access$100(OuterClass.java:3)
at OuterClass.main(OuterClass.java:12)
These nested classes are compiled into two distinct class files OuterClass.class and OuterClass$InnerClass.class. You can see that the compiler has inserted the synthetic method access$100 into OuterClass$InnerClass which allows the main method of OuterClass to invoke the private method test of the inner class. This inner class method in turn invoked a synthetic method access$000 in the outer class which allows the invocation of privateMethod() in OuterClass.
Note that this kind of access is different to the access to private members performed with Java 8’s lambda expressions and method references. For the member access performed in that context, no helper methods are generated by the compiler and the way the JVM makes the access possible is intentionally unspecified, but we can say that for Oracle’s current JRE implementation, there will be a runtime-generated class which is indeed capable of bypassing the access restriction of private members, e.g.
import java.util.function.Consumer;
public class OuterClass {
static class InnerClass {
static final Consumer<Runnable> TEST_METHOD=InnerClass::test;
private static void test(Runnable outerMethod) {
outerMethod.run();
}
}
private static void privateMethod() {
Thread.dumpStack();
}
public static void main(String[] args) {
System.out.println(System.getProperty("java.version"));
InnerClass.TEST_METHOD.accept(OuterClass::privateMethod);
}
}
As of 1.8.0_65, it prints:
java.lang.Exception: Stack trace
at java.lang.Thread.dumpStack(Thread.java:1329)
at OuterClass.privateMethod(OuterClass.java:12)
at OuterClass$InnerClass.test(OuterClass.java:8)
at OuterClass.main(OuterClass.java:16)
Not showing such helper methods, but also filtering out the runtime-generated classes. Changing privateMethod() to
private static void privateMethod() {
for(StackTraceElement e:Thread.getAllStackTraces().get(Thread.currentThread()))
System.out.println("\tat "+e);
}
reveals
at java.lang.Thread.dumpThreads(Native Method)
at java.lang.Thread.getAllStackTraces(Thread.java:1603)
at OuterClass.privateMethod(OuterClass.java:12)
at OuterClass$$Lambda$2/135721597.run(Unknown Source)
at OuterClass$InnerClass.test(OuterClass.java:8)
at OuterClass$InnerClass$$Lambda$1/471910020.accept(Unknown Source)
at OuterClass.main(OuterClass.java:16)
with the generated classes having fancy names like OuterClass$InnerClass$$Lambda$1/471910020 and OuterClass$$Lambda$2/135721597 which are accessing the private members. Note that the generation of these classes has been triggered by the classes which have the right to access these private members, which has been checked before allowing to create such function objects.

Access private method having parameter with private access specifier

I am writing a Junit for a method with multiple parameters and having private access specifier. I am using Java reflection to achieve this. However, one of the parameter for this private method is private class. I am doing below:
ClassHavingPrivateMethod object = new ClassHavingPrivateMethod();
object.getClass().getDeclaredMethod(PRIVATE_METHOD_NAME, Param1.class, <This parameter is a private class Inside ClassHavingPrivateMethod>)
How can I proceed?
EDIT
I agree on the point that I should not write a test case for a private method with reflection and it should always be accessed through a wrapper public method. However, is there any way to achieve the above objective through reflection. Even though, I am not going to write my test case through reflection but I am eager to know about it.
Any help is really appreciated.
One of the way you can try by changing the access from private to default. By changing the access level to default the method can be accessed only from the same package (still restricted access) on the other hand since your test class and class under test will be under same package , the test class can call that method directly, without doing any trick.
Example :
package com.test;
class SomeClass {
String defaultMethod(){
...
}
}
package com.test;
class SomeClassTest {
public void testDefaultMethod(){
SomeClass testObject = new SomeClass();
testObject.defaultMethod();
}
}
Hope it will help.

Quick Java Question: Instantiating a given class only from another?

My problem is thus: I need a way to ensure only one given class can instantiate another. I don't want to have to make the other a nested inner class or something dumb like that. How do I do this? I forget offhand.
A private static inner class is exactly what you want. Nothing dumb about it.
public class Creator {
private static class Created {
}
}
Otherwise you can only protect instantiation on the package level.
public class Created {
Created() {
}
}
Which gives only classes from the same package access to the constructor.
Make the constructor private. Create a static factory method that takes an instance of the class that is allowed access. Have the factory method create a suitable object and use a settor on the object that is allowed access to the created object to give that class the created copy.
public class AllowedAccess
{
private SecureClass secure;
public setSecureClass( SecureClass secure )
{
this.secure = secure;
}
...
}
public class SecureClass
{
private SecureClass() {}
public static void Create( AllowedAccess allowed )
{
allowed.setSecureClass( new SecureClass() );
}
...
}
BTW, I'm suspicious of this design. Seems too highly coupled to me.
You could make the class that is to be protected from instantiation package private.
I agree with tvanfosson's answer and also with his comment about too high coupling. Why don't you retain more control of you class creation process by adopting an Inversion of Control framework like Spring or Guice?
IMHO creating classes with the "new" statement is to be considered a bit... obsolete, factories are to be preferred and IoC frameworks even more.
Regards

Categories

Resources